Rails推入数组保存对象

use*_*495 11 activerecord ruby-on-rails-3

我有一个有趣的问题.我正在使用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
Run Code Online (Sandbox Code Playgroud)

出于某种原因,当客户被推入阵列时,会调用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
Run Code Online (Sandbox Code Playgroud)

dee*_*our 22

<< 是别名 push

ActiveRecord::Associations::CollectionProxy电话中concat

哪个叫 concat_records

在那里你可以看到插入发生.

因此,使用现有记录(持久存储到数据库中),运行<<.push将记录插入集合中,必要时将它们持久保存到数据库中.<<正如你所做的那样,调用一个数组,而不是记录集

random_array << customer
Run Code Online (Sandbox Code Playgroud)

调用Ruby的<<Array方法,而不是AR等价物(如你所见,在这种情况下不会发生保存).

编辑:要清楚,您找到的解决方法或多或少是我通常处理您正在处理的情况; 我的回答更侧重于为什么 <<会有这种行为.