忘れたときはここを見ろ。この広告は、90日以上更新していないブログに表示しています。その6RoRさて、これまで幾つかの方法を記しておいたが、どれもアドホック、その場凌ぎの辛うじて小規模な開発で許されるような拙い方法であることは否めない。RoRに相応しい洗練された美しい方法がある。その方法を用いなければ、例えば親子関係があるテーブルの子テーブルの情報を編集するのに、ビューでその子の個数を増減させたり新規作成・編集してからDBに保存するといった処理をするのに態々少し複雑なコードを書かなくてはならなくなる。今回はその方法を書き残しておく。使った動的に子情報のためのフォームを増減させられる例を示したページは幾つかあるが、今回は次のサイトを参考にした:ruby-rails.hatenadiary.com上記サイトではUser(親)とAddress(子)という関係のモデルをつかっているが、この備忘録ではCustomer(親)とShipping(子)とした。顧客(customer)の発送先(shpipping)が複数あるかもしれないから発送先の住所(address)入力してもらおうという感じで、Amazonなどを思い出すと分かり易いだろう。モデルCustomerが複数のモデルShppingを全くもたないか、一つ以上持ち、Shppingにはadddressという属性があるとする。環境やバージョンによっては、双方向関連付けを「明示」しておいてその関係を通知させるようにしておかないと、エラーがおきたり思った通りに動かなかったりすることがあるだろう。scaffoldから作れば10分もかからずにできてしまうだろう。実現方法カラムと一致しない項目がある入力フォームにするカラムと一致しない項目がある入力フォームにしないと始まらない。前出の具体例を参考に、子フォームの増減やCRUD処理が動くことが確認できたら、この備忘録ではshippingのaddressを、以前の備忘録のように、フォームでは直接入力できず、state(都道府県)、city(市区町村)、street(町名字番地等)に分けて入力することにし、格納するときはその三つの項目を半角項目を挟んで一つの文字列にすることにする。%></fieldset>いつものことだが、書き換える前のコードをコメントアウトして残している。コントローラーRailsのモデルの仕様を理解すればコントローラーの変更箇所は少なくて済む。なんとStrongParameterを実行する箇所だけ変更すればよい。endadrressをstate、city、streetの三つに書き換えている。idがあるおかげで複数のshippingを扱え、_destroyがあるおかげで個別に削除が可能となっている。モデル以前まではコントローラー中にストロングパラメーターを無事に通過して得たハッシュから新規作成または更新すべき情報を作りだしていたが、そういった処理全てモデル内でしかもカプセル化することが可能である。様々なタイミングで実行することができるコールバック(フック)が何種類も用意してあり、それを利用して実現する。新規作成時Railsのコールバックのタイミングを詳しく記したページに譲るが、DBに新規に書き込む書き込む前に、バリデーションがあればバリーデーションを実行するが、before_validationでメソッドなどを指定しておけばバリデーション前にその処理を実行することが可能である。この備忘録の場合、その処理でstate、city、streetからaddressの文字列を合成すればよい。ソースコードは更新時と一緒に示す。endendコメントアウトしているロガーを機能させれば動作がよくわかる。更新のとき、先ずコントローラーのeditの処理が走る。フォームでボタンが押されると、コントローラーのupdate処理が走る。editとupdate、そのどちらでもモデルのfindメソッドによって該当するレコードの情報をモデルに移しているのは既に分かっていることだろう。editの処理においては、コールバックafter_findで呼び出された上記のsplit_addressを実行すると、addressにあった情報が、フォーム用のstate、city、streetに移され、adressはblankにされる。フォームでsubmitされた後、再度、addressからstate、city、streetに情報が分割されて格納され、そのあとでaddressがblankにさられる。モデルのupdateメソッドがコントローラーで実行されると、直ぐにbefore_validationで登録された処理make_adressが走る。ここで、state、city、streetに変更がなかった場合、addressはDBからモデルに移した時と同じ値を持つので変更の必要がなく、更新処理は終了し、DBの更新も生じない。その三つのうちどれか変更があれば、その三つからaddressに合成された情報と、DBからモデルに移した時のaddressが異なるので変更があったとみなされ、DBへの更新処理が始まる。»プロフィールid:Matthew忘れたときはここを見ろ。(1)リンクはてなブログブログをはじめる週刊はてなブログはてなブログProはてなブログをはじめよう!Matthewさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。