2012-06-15 81 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 

即连铸活动记录关联到真实阵列对象,所以<<方法将是正常数组#推送方法。