忍者ブログ
ブログツール、2007/11/06作成
[66] [65] [64] [63] [62] [61
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

久しぶりにRailsに戻ってきたら、あまりにもバージョンが違いすぎてて、なんか浦島太郎気分。

で、ActiveRecordで関連を持ったときに、保存の伝播の仕方が混乱してきたので整理してみた。

結論を先に言うと、
親のメソッドで代入したときはsaveの伝播はなされるが、子のメソッドから代入したときはsaveの伝播はなされない。
つまり、has_many, has_oneとbelongs_toは独立して動作する、ということ。

ふむ。シンプル。

試しにプロジェクト作ってみて、動かして確認。
HogeParent
has_many :hoge_children
has_one :hoge_has_one

HogeChildren
belongs_to :hoge_parent

HogeHasOne
belongs_to :hoge_parent

親は未保存
hoge_parent = HogeParent.new
hoge_parent.name = "post_save hoge"
hoge_parent.new_record? = true
hoge_child = HogeChild.new
hoge_child.name = "post_save child"
hoge_child.new_record? = true
hoge_has_one = HogeHasOne.new
hoge_has_one.name = "post_save has_one"
hoge_has_one.new_record? -> true
親が未保存の時、親のメソッドで代入する
hoge_parent.hoge_children << hoge_child
hoge_child.hoge_parent_id -> nil
hoge_child.new_record? -> true
hoge_parent.hoge_has_one = hoge_has_one
hoge_has_one.hoge_parent_id -> nil
hoge_has_one.new_record? -> true
当然のことながら、この時点では何も起こらない

親が未保存の時に親のメソッドで代入したもので、親を保存したとき
hoge_parent.save
hoge_parent.new_record? -> false
hoge_child.new_record? -> false
hoge_child.hoge_parent_id -> 10
hoge_has_one.new_record? -> false
hoge_has_one.hoge_parent_id -> 10
親の保存が伝播して、子のhoge_prent_idに自動的にIDが保存され、子も一緒にsaveされる

親を先に保存する
saved_hoge_parent = HogeParent.new
saved_hoge_parent.name = "pre_save hoge"
saved_hoge_parent.save -> true
saved_hoge_parent.new_record? -> false
saved_hoge_parent.id -> 11 
saved_hoge_parent.new_record? = false
saved_hoge_child = HogeChild.new
saved_hoge_child.name = "pre_save child"
saved_hoge_child.new_record? = true
saved_hoge_has_one = HogeHasOne.new
saved_hoge_has_one.name = "pre_save has_one"
saved_hoge_has_one.new_record? -> true
親を先に保存して、親のメソッドで代入
saved_hoge_parent.hoge_children << saved_hoge_child
saved_hoge_child.new_record? -> false
saved_hoge_child.hoge_parent_id -> 11
saved_hoge_parent.hoge_has_one = saved_hoge_has_one
saved_hoge_has_one.new_record? -> false
saved_hoge_has_one.hoge_parent_id -> 11
代入が成功した時点で、自動的にhoge_parent_idが格納されてsaveが呼ばれる

親が未保存
post_save_hoge_parent = HogeParent.new
post_save_hoge_parent.name = "post_save hoge"
post_save_hoge_parent.new_record? = true
post_save_hoge_child = HogeChild.new
post_save_hoge_child.name = "post_save child"
post_save_hoge_child.new_record? = true
post_save_hoge_has_one = HogeHasOne.new
post_save_hoge_has_one.name = "post_save has_one"
post_save_hoge_has_one.new_record? -> true
親が未保存で、子のメソッドで代入
post_save_hoge_child.hoge_parent = post_save_hoge_parent
post_save_hoge_child.new_record? -> true
post_save_hoge_child.hoge_parent_id -> nil
post_save_hoge_has_one.hoge_paent = post_save_hoge_parent
post_save_hoge_has_one.new_record? -> true
post_save_hoge_has_one.hoge_parent_id -> nil
親が未保存で、子のメソッドで代入したもので、親を保存したとき
post_save_hoge_parent.save -> true
post_save_hoge_parent.new_record? -> false
post_save_hoge_parent.id -> 12
post_save_hoge_child.new_record? -> true
post_save_hoge_child.hoge_parent_id -> nil
post_save_hoge_has_one.new_record? -> true
post_save_hoge_has_one.hoge_parent_id -> nil
親のsaveは伝播しない。子のhoge_parent_idも更新されない

親を先に保存
pre_saved_hoge_parent = HogeParent.new
pre_saved_hoge_parent.name = "pre_save hoge"
pre_saved_hoge_parent.save -> true
pre_saved_hoge_parent.new_record? -> false
pre_saved_hoge_parent.id -> 13 
pre_saved_hoge_parent.new_record? = false
pre_saved_hoge_child = HogeChild.new
pre_saved_hoge_child.name = "pre_save child"
pre_saved_hoge_child.new_record? = true
pre_saved_hoge_has_one = HogeHasOne.new
pre_saved_hoge_has_one.name = "pre_save has_one"
pre_saved_hoge_has_one.new_record? -> true
親を先に保存して、子のメソッドで代入
pre_saved_hoge_child.hoge_parent = pre_saved_hoge_parent
pre_saved_hoge_child.new_record? -> true
pre_saved_hoge_child.hoge_parent_id -> 13
pre_saved_hoge_has_one.hoge_parent = pre_saved_hoge_parent
pre_saved_hoge_has_one.new_record? -> true
pre_saved_hoge_has_one.hoge_parent_id -> 13
自動的に保存はされない。当たり前だが、すでに親のIDはわかっているので、hoge_parent_idは格納されている
PR
この記事にコメントする
name
title
color
mail
URL
comment
pass   Vodafone絵文字 i-mode絵文字 Ezweb絵文字
secret (チェックを入れると管理人だけに表示できます)
ついめ~じ
ブログ内検索
フリーエリア
サニーカメラ
Powered by Ninja Blog    template by Temp* factory    icon by MiniaureType

忍者ブログ [PR]