4

我有一个项目ActiveRecords,我正在尝试使用一个块为每个项目设置一个默认值(“测试项目”)。
在这个表达式中:

list = {"type1", "type2", "type3", "type4", "..."}
list.each { |name| @item.attributes["#{name}"] = "Test item"] }

值未设置。

我必须使用@item.attributes["#{name}"]插值,因为我不能对每个项目都这样做:

@item.tipe1 = "Test item"

那么,第一个语句会发生什么?为什么?如果我想做的事情不可能那样做,我怎么能做同样的事情?

4

3 回答 3

2

为此,您可以使用 send 方法。或许是这样的:

list = {"type1", "type2", "type3", "type4", "..."}
list.each { |name| @item.send("#{name}=", "Test item") }
于 2011-01-21T02:09:34.617 回答
2

赋值@items.attributes["#{name}"] = "Test item"]不起作用,因为attributes每次调用该方法都会返回一个新的 Hash 对象。@items所以你并没有像你想象的那样改变 ' 对象的值。相反,您正在更改已返回的新 Hash 的值。并且这个哈希在每次迭代后都会丢失(当然当each块完成时)。

一种可能的解决方案是使用 ' 属性的键创建一个新的 Hash@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
于 2011-01-21T02:40:27.167 回答
1

我认为问题在于您只更改返回的属性哈希,而不是 ActiveRecord 对象。

您需要执行以下操作:

# make hash h
@items.attributes = h

按照你的例子,也许是这样的:

@items.attributes = %w{type1 type2 type3 type4}.inject({}) { |m, e| m[e] = 'Test item'; m }

顺便说一句,"#{e}"与 String 表达式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 的建议并使用发送。

于 2011-01-21T02:03:04.820 回答