2009-05-15 21 views
7

モデルのコレクション内の個々のアイテムの変更を保存する必要がありますか、モデルを保存するときに呼び出す方法があります。Rails/ActiveRecord:モデルの関連するコレクションへの変更を保存

#saveそうではありません。例:上記の例で

irb> rental = #... 
#=> #<Rental id: 18737, customer_id: 61, dvd_id: 3252, date_rented: "2008-12-16 05:00:00", date_shipped: "2008-12-16 05:00:00", date_returned: "2008-12-22 05:00:00"> 
irb> rental.dvd 
#=> #<Dvd id: 3252, title: "The Women of Summer", year: 1986, copies: 20, is_new: false, is_discontinued: false, list_price: #<BigDecimal:1a48f0c,'0.1599E2',8(8)>, sale_price: #<BigDecimal:1a48ed0,'0.1599E2',8(8)>> 
irb> rental.dvd.copies += 1 
#=> 21 
irb> rental.save 
#=> true 
irb> rental.dvd 
#=> #<Dvd id: 3252, title: "The Women of Summer", year: 1986, copies: 21, is_new: false, is_discontinued: false, list_price: #<BigDecimal:1a2e9cc,'0.1599E2',8(8)>, sale_price: #<BigDecimal:1a2e97c,'0.1599E2',8(8)>> 
irb> Dvd.find_by_title('The Women of Summer') 
#=> #<Dvd id: 3252, title: "The Women of Summer", year: 1986, copies: 20, is_new: false, is_discontinued: false, list_price: #<BigDecimal:1a30164,'0.1599E2',8(8)>, sale_price: #<BigDecimal:1a30128,'0.1599E2',8(8)>> 

、レンタルが持っているDVDのコピーは、DB(コピーの異なる数に注意してください)にコピーを更新していないようです。

答えて

2

だけrental.dvd.saveを行う「を!」増分で!

1

これはあなた自身で行う必要があります。 Active Record does not cascade save operations in has_many relations after the initial save.

before_saveコールバックを使用してプロセスを自動化できます。

+0

私はbefore_saveコールバックのアイデアを好きですが、私は爆発的再帰を心配したい - 私はここにある別のシナリオでは、顧客とDVDそれぞれが多くのレンタルを持っているので、私は、customer.rentals.first.dvd.rentals.first.customerと言うことができますし、カスケードbefore_savesは少し手を出すかもしれない、と心配します。 – rampion

2

は、あなたは完全に真のこの自分

このありえを行う必要があります。保存を強制する「ビルド」メソッドを使用することができます。たとえば、会社のモデルと従業員(会社has_many従業員)があるとします。すべての4つのレコードを作成し、会社の記録と3枚の従業員レコードとのcompany_idが適切Employeeオブジェクトに押し下げられる

acme = Company.new({:name => "Acme, Inc"}) 
acme.employees.build({:first_name => "John"}) 
acme.employees.build({:first_name => "Mary"}) 
acme.employees.build({:first_name => "Sue"}) 
acme.save 

:あなたのような何かを行うことができます。あなたが値またはあなたも自動的に注意し、保存されます

rental.dvd.increment!(:copies) 

使用することができ、この場合のインクリメント後

+3

新しいモデルの作成を指しています。あなたが参照する質問と答えは、既存のモデルの変更を保存することを指しています。 –

+0

これは、新しいモデルインスタンスの場合にのみ機能することに注意してください。 – Obie

22

アソシエーションを宣言するときに:autosave => trueオプションを追加することで、モデルのコレクション内のアイテムへの変更をカスケード保存するようにActiveRecordを設定できます。 Read more

例:

class Payment < ActiveRecord::Base 
    belongs_to :cash_order, :autosave => true 
    ... 
end 
関連する問題