11

興味深い問題があります。Ruby 1.9.2 と Rails 3.1.3 を使用しています。

簡単にするために、顧客と店舗としましょう。店舗には多くの顧客がおり、顧客は店舗に属しています。私は店舗のすべての顧客を収集し、後で値を設定できる場所をいくつか作成しようとしています。代わりに、予期しないときに 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
4

2 に答える 2

22

<<のエイリアスですpush

ActiveRecord::Associations::CollectionProxy通話中concat

呼び出すconcat_records

挿入が行われているのを見ることができます。

したがって、既存のレコード(データベースに永続化されている)を使用して、実行中<<または.pushコレクションにレコードを挿入し、必要に応じてそれらをデータベースに永続化します。<<あなたがやっているように、レコードコレクションではなく配列を呼び出す

random_array << customer

ARに相当するものではなく、 Rubyの<<Arrayメソッドを呼び出します(ご覧のとおり、この場合、保存は行われません)

編集:明確にするために、あなたが見つけた回避策は、多かれ少なかれ、あなたが扱っている状況を私が通常どのように処理するかです。私の答えは、なぜ <<この振る舞いをするのかにもっと焦点を当てています。

于 2012-06-15T00:59:56.650 に答える