2012-06-15 80 views
11

我有一個有趣的問題。我正在使用Ruby 1.9.2和Rails 3.1.3。Rails推入陣列保存對象

我有2個模型,簡化讓我們說客戶和商店。 商店有許多顧客,而顧客屬於商店。 我試圖收集所有商店的顧客,並創建一個地方供我稍後填充值。相反,當我不期望的時候會調用customer.save。

store = Store.find(1) 
customers_array = store.customers 
random_array = Array.new 
customers_count = customers_array.count + 1 

(customers_count..2).each do |i| 
    customer = Customer.new 
    c.id = "#{i}000000000000" 
    random_array << customer # this line doesn't call customer.save 
    customers_array << customer # this line calls customer.save when store has customers 
end 

由於某些原因,當客戶被推入數組時,customer.save被調用。 它不會發生,如果你推到一個數組是一個普通的數組而不是一個關係。

我發現了一種解決方法,但我仍然想知道爲什麼會發生這種情況。 解決方法:

store = Store.find(1) 
initial_customers_array = store.customers 
additional_customers_array = Array.new 
customers_count = initial_customers_array.count + 1 

(customers_count..2).each do |i| 
    customer = Customer.new 
    c.id = "#{i}000000000000" 
    additional_customers_array << customer 
end 
customers_array = initial_customers_array + additional_customers_array 
+1

對於那些尋找解決方案而不是爲什麼:在集合上使用''build'''來創建一個模型而不保存它:http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods .html#module-ActiveRecord :: Associations :: ClassMethods-label-Collections – blu

+0

我有相反的問題。在模型規範中使用'build',然後使用<<向集合添加項目不起作用。這個問題的答案解釋了爲什麼不。 – CJBrew

回答

21

<<處於ActiveRecord::Associations::CollectionProxy呼籲push

其中別名concat

它調用concat_records

在這裏可以看到插入件的發生。

因此,與現有的記錄(持久化到數據庫),運行<<.push將記錄插入收集,如有必要,他們堅持到數據庫中。在一個陣列,而不是記錄集調用<<,因爲你在

random_array << customer 

做調用Ruby的<<陣列方法,而不是AR相當於(如你發現沒有保存發生在這種情況下)

編輯:要清楚,你找到的解決方法或多或少是我通常處理你處理的情況;我的答案更關注爲什麼<<有這種行爲。

3

解決此另一種方法是改變你(你的原代碼)第二行:

customers_array = store.customers.to_a 

即連鑄活動記錄關聯到真實陣列對象,所以<<方法將是正常數組#推送方法。