【问题标题】:ActiveModel dynamic attributesActiveModel 动态属性
【发布时间】:2013-05-15 17:27:35
【问题描述】:

对不起,如果我的问题很愚蠢,但我花了很多时间搜索解决方案,但我没有找到。

我想创建一个没有数据库的ApiOutputsHandler 模型。所以我创建了一个 ActiveModel。 此模型将用于我的 API 的自定义响应,例如错误(但不仅限于)。我已经使用了 send() 方法给这个模型添加了属性,但是觉得它很糟糕......

class ApiOutputsHandler

  attr_accessor :status, :type, :message, :api_code, :http_code, :template

  ERR_TYPES = {
    :permanent_quota_limit => { :type => 'PermanentLimitException', :message => 'Quota limit reached for this action', :api_code => 700, :http_code => 401 } 
  }

  def initialize(data)
    data.each do |name, value|        
      send("#{name}=", value)  
    end
  end

  def error()
    send('status=','error')
    send('template=','api/v1/api_outputs_handler/output')
    return self
  end

  def new
    return self
  end

end

然后,我像这样实例化我的对象

@output = ApiOutputsHandler.new(ApiOutputsHandler::ERR_TYPES[:permanent_quota_limit]) 
return @output.error()

我会推荐很多ERR_TYPES(这就是兴趣所在)。 你认为有更好的方法吗?

当我检查创建的对象时,它看起来像这样:

#<ApiOutputsHandler:0x000000036a6cd0 @type="PermanentLimitException", @message="Quota limit reached for this action">

你看到属性前面的 arobase 了吗?为什么我得到的是那个而不是普通的:

#<ApiOutputsHandler:0x000000036a6cd0 type: "PermanentLimitException", message: "Quota limit reached for this action">

感谢您的帮助!

【问题讨论】:

  • 您的问题是关于更改对象在控制台中的外观吗?
  • 其实有2个问题。 1-您认为有更好的方法吗? 2-是的,我可以更改对象方​​面以获得与 ActiveRecord 相同的类型吗?谢谢你

标签: ruby-on-rails ruby-on-rails-3 activemodel active-model-serializers


【解决方案1】:

是的,有更好的方法来做到这一点。以下是我的做法:

class ApiOutputsHandler
  attr_accessor :status, :type, :message, :api_code, :http_code, :template

  ERR_TYPES = {
    :permanent_quota_limit => { :type => 'PermanentLimitException', :message => 'Quota limit reached for this action', :api_code => 700, :http_code => 401 } 
  }

  def initialize(data)
    # added it here so that you can pass symbol error code to initializer
    data = ERR_TYPES[data] if data.is_a?(Symbol)

    data.each do |name, value|        
      send("#{name}=", value)  
    end
  end

  def error
    self.status = 'error'
    self.template= 'api/v1/api_outputs_handler/output'
    self
  end
end

这样,你可以只将符号错误代码传递给初始化器,如下所示:

handler = ApiOutputsHandler.new(:permanent_quota_limit)

您还可以更改对象在控制台中的外观,您只需重新定义#inspect 方法。在您的情况下,它可能如下所示:

def inspect
  "#<#{self.class.name} type: #{type}, message: #{message}>" # etc
end

【讨论】:

  • 谢谢。最后一个问题:有什么方法可以用ERR_TYPES[data] Hash 自动创建/填充我的对象属性而不是data.each do |name, value| send("#{name}=", value) end 再次感谢。
  • 我觉得你目前的做法还可以。
猜你喜欢
  • 1970-01-01
  • 2019-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
  • 2012-08-23
相关资源
最近更新 更多