我有一个有趣的问题。我正在使用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
答案 0 :(得分:22)
<<
是push
ActiveRecord::Associations::CollectionProxy
调用concat
调用concat_records
您可以在其中看到插入内容。
因此,对于现有记录(持久存储到数据库中),运行<<
或.push
会将记录插入集合中,并在必要时将它们保存到数据库中。在数组上调用<<
,而不是在
random_array << customer
调用Ruby的<<
数组方法,而不是AR等效的(如您所见,在这种情况下不会发生保存)。
编辑:要明确,您找到的解决方法或多或少是我通常处理您正在处理的情况;我的回答更多地关注为什么 <<
有这种行为。
答案 1 :(得分:4)
另一种解决方法是将您的第二行(原始代码)更改为:
customers_array = store.customers.to_a
将活动记录关联强制转换为实际数组对象,因此<<
方法将是正常的数组#推送方法。