【问题标题】:instance_variable_set (:@attributes, { :brand.to_s => "Apple" } ) overwrites all attributes instead of addinginstance_variable_set (:@attributes, { :brand.to_s => "Apple" } ) 覆盖所有属性而不是添加
【发布时间】:2010-12-08 04:07:37
【问题描述】:

背景...

我正在编写一个解析器,它查看字符串并尝试确定它们可能包含哪些产品。我创建了自己的 Token 类来提供帮助。

class Token < ActiveRecord::BaseWithoutTable

  attr_accessor :regex
  attr_accessor :values

end

令牌示例:

Token.new(:regex => /apple iphone 4/, :values => { :brand => "Apple", :product => "iPhone", :version => 4})

(其中哈希键都对应产品表中的数据库列。)

问题出在:在我的Parser 中,当找到Token 时,我尝试将关联的值添加到Product 实例中,如下所示:

token.values.each do |v|
   attrib, value = v[0], v[1]
   my_product.instance_variable_set(:@attributes, { attrib.to_s => value })
end

这可行,只是我似乎必须同时设置所有属性。如果我分阶段进行(即:当我发现新令牌时),它会用nil 覆盖任何未指定的属性。我错过了什么吗?有没有更好的方法来做到这一点?

【问题讨论】:

  • 我们可以看看你的Product 模特吗?
  • 您使用instance_variable_set 是否有任何特殊原因,或者您只是想更新token.values 返回的Hashkey 表示的属性?

标签: ruby-on-rails


【解决方案1】:

修改现有值(如果存在)而不是覆盖它:

if attr = my_product.instance_variable_get :@attributes
  attr[attrib.to_s] = value
else
  my_product.instance_variable_get :@attributes, { attrib.to_s => value }
end

instance_variable_set 的使用似乎很粗略;为什么Product 本身没有访问器?

class Product
  def attributes
    @attributes ||= {}
  end
end

...

token.values.each do |attr,v|
   my_product.attributes.merge!( attr.to_s => v )
end

【讨论】:

  • 它有效,但你能解释一下“@attributes ||= {}”到底在做什么吗?
  • @vmardian 这和@attributes = @attributes || {}一样;这是common Ruby idiom“将此变量设置为此值,除非它已被设置”。 (如果你想显式设置nilfalse,它实际上不会这样工作,但这是一种罕见的边缘情况。)
【解决方案2】:

如果my_productactive_record 对象,则可以使用write_attribute 代替instance_variable_set。请注意,这只会写入属性,即数据库列:

token.values.each do |v|
   attrib, value = v[0], v[1]
   my_product.write_attribute attrib.to_s, value # attrib.to_sym would work too
end

另外,如果token.values 返回Hash,您可以这样进行迭代:

token.values.each do |k, v|
   my_product.write_attribute k, v
end

【讨论】:

    猜你喜欢
    • 2017-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    • 2020-07-17
    • 1970-01-01
    相关资源
    最近更新 更多