accepts_nested_attributes_for でupdateされないパターン
ちょっとハマったのでメモ。
class User < ActiveRecord::Base attr_accessible :name, :profile_attributes has_one :profile accepts_nested_attributes_for :profile end class Profile < ActiveRecord::Base attr_accessible :name, :user_id belongs_to :user end
こんなモデルがあったとき、Userを更新したりするとProfileも一緒に更新してくれる。
が、更新しないときもある。
Userのみロードしてたとき
user = User.where(:id => 123).first user.name = 'hoge' user.save! #=> Profileのsaveは走らない
UserからProfileを参照した後
user = User.find(123) name = user.profile.name user.name = name user.save! #=> Profileのsaveが走る
ProfileからUserをとって更新したとき
profile = Profile.find_by_user_id(123) user = profile.user user.name = 'aaa' user.save! #=> Profileのsaveは走らない
つまり、accepts_nested_attributes_for宣言しているモデルが対象のモデルへの参照を握っている場合は一緒にsaveが走るっぽくて、逆の参照持ってても走らないっぽい。まあsaveの主体がどっちかってのを考えれば自然か。
たぶんacriverecordのattribute_will_changeに追加されるとこのコードをもっと読めばはっきりしそう。
うっかりすると、accepts_nested_attributes_for対象のvalidationに引っかかったりするトラップが待っている。