我有一个项目ActiveRecords
,我正在尝试使用块为每个项目设置默认值(“测试项目”)。
在这个表达式中:
list = {"type1", "type2", "type3", "type4", "..."}
list.each { |name| @item.attributes["#{name}"] = "Test item"] }
未设置值。
我必须使用@item.attributes["#{name}"]
进行插值,因为我无法为每个项目执行此操作:
@item.tipe1 = "Test item"
那么,第一个声明会发生什么?为什么?如果以这种方式我不想做什么,我怎么能这样做呢?
答案 0 :(得分:2)
您可以将send方法用于此目的。也许是这样的:
list = {"type1", "type2", "type3", "type4", "..."}
list.each { |name| @item.send("#{name}=", "Test item") }
答案 1 :(得分:2)
赋值@items.attributes["#{name}"] = "Test item"]
不起作用,因为每次调用attributes
方法都会返回一个新的Hash对象。所以你没有像你想象的那样改变@items
'对象的值。相反,您正在更改已返回的新哈希值。每次迭代后(当each
块完成时),此哈希都会丢失。
一种可能的解决方案是使用@items
'属性的键创建一个新哈希,并通过attributes=
方法进行分配。
h = Hash.new
# this creates a new hash object based on @items.attributes
# with all values set to "Test Item"
@items.attributes.each { |key, value| h[key] = "Test Item" }
@items.attributes = h
答案 2 :(得分:1)
我认为问题在于您只是更改返回的属性哈希,而不是ActiveRecord对象。
您需要执行以下操作:
# make hash h
@items.attributes = h
按照你的例子,可能是这样的:
@items.attributes = %w{type1 type2 type3 type4}.inject({}) { |m, e| m[e] = 'Test item'; m }
BTW,"#{e}"
与字符串表达式e
或任何类型:e.to_s
相同。第二个例子,也许更容易阅读:
a = %w{type1 type2 type3 type4}
h = {}
a.each { |name| h[name] = 'test item' }
@items.attributes = h
使用attributes=
方法可能适用于哈希常量,例如:
@items.attributes = { :field => 'value', :anotherfield => 'value' }
对于完全生成的属性,您可以采用DanneManne's建议并使用send。