Rails推入数组保存对象

时间:2012-06-15 00:16:43

标签: ruby-on-rails-3 activerecord

我有一个有趣的问题。我正在使用Ruby 1.9.2和Rails 3.1.3。

我有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

2 个答案:

答案 0 :(得分:22)

<<push

的别名

ActiveRecord::Associations::CollectionProxy调用concat

调用concat_records

您可以在其中看到插入内容。

因此,对于现有记录(持久存储到数据库中),运行<<.push会将记录插入集合中,并在必要时将它们保存到数据库中。在数组上调用<<,而不是在

中调用记录集合
random_array << customer

调用Ruby的<<数组方法,而不是AR等效的(如您所见,在这种情况下不会发生保存)

编辑:要明确,您找到的解决方法或多或少是我通常处理您正在处理的情况;我的回答更多地关注为什么 <<有这种行为。

答案 1 :(得分:4)

另一种解决方法是将您的第二行(原始代码)更改为:

customers_array = store.customers.to_a

将活动记录关联强制转换为实际数组对象,因此<<方法将是正常的数组#推送方法。