2011-01-21 107 views
4

我有一個項目ActiveRecords,我正在嘗試使用一個塊爲它們中的每個設置默認值(「測試項目」)。
在此表達式中:設置屬性的問題

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

值未設置。

我必須使用@item.attributes["#{name}"]進行插值,因爲我不能這樣做的每一個項目:

@item.tipe1 = "Test item" 

所以,在第一條語句會發生什麼?爲什麼?如果我想這樣做是不可能的,我怎麼能做到這一點?

回答

2

分配@items.attributes["#{name}"] = "Test item"]不起作用,因爲attributes方法返回每次調用它一個新的Hash對象。所以你不會像你想的那樣改變@items'物品的價值。相反,您正在更改已返回的新哈希值。這個哈希在每次迭代後都會丟失(當然,當each塊已經完成時)。

一個可能的解決方案是用@items'屬性的鍵創建一個新的Hash,並通過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 
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建議和使用發送。

+0

我認爲你的回答是最好的,但丹尼爾和他的描述讓我更容易理解我的煩惱。 – user502052 2011-01-21 02:59:13

2

您可以使用send方法來達到此目的。也許是這樣的:

list = {"type1", "type2", "type3", "type4", "..."} 
list.each { |name| @item.send("#{name}=", "Test item") }