【結論】
・「accepts_nested_attributes_for」は
モデルのアソシエーションのオプション
・このメソッドを親モデルに定義すると
データを保存した際に
アソシエーション先の子レコードも
同時に保存が行える
【目次】
【本題】
関連モデルにも同時保存がしたい場合
あるモデルのデータを保存した際、
その子モデルも同時に情報を保存したい場合があります。
例えば、下記の様な
アソシエーションが組まれたテーブルがあったとします。
Post(1) <<< >>> PostState(多)
Postという親モデルに、投稿した情報が記録されており、
その子モデルであるPostStateに、投稿の更新情報が都度記録されています。
この場合、下記の様に@post.saveの後に、
@post_stateを保存する記述をする方法があります。
def create @post = Post.new(post_params) if @post.save @post_state = PostState.new(post_id: post.id, description: messege) @post_state.save redirect_to post_path else render :new end end private def post_params params.require(:post).permit(:id, :title, :body) end
但し、この場合updateにも同様の記述をする必要があったりと
冗長なコードになってしまいます。
そこで登場するのが「accepts_nested_attributes_for」です
「accepts_nested_attributes_for」について
「accepts_nested_attributes_for」は、
モデルに記述するオプションの一種です。
これを親モデルに記述すると、親モデルを保存した際、
アソシエーション先の子モデルの保存も一緒に実行されます。
実装方法は、下記の様に親モデルに記述します。
class PostsController < ApplicationController has_many :post_state, dependent: :destroy accepts_nested_attributes_for :post_state
後は、親モデルに渡すストロングパラメータに
子モデルに保存する情報も追記すれば、実装完了です
def create @post = Post.new(post_params) if @post.save redirect_to post_path else render :new end end private def post_params params.require(:post).permit(:id, :title, :body, :description) end
見た目もスッキリして、管理しやすくなりました。
参考リンク
《今日の学習進捗(3年以内に10000時間に向けて)》
学習開始からの期間 :110日
今日までの合計時間:1030h
一日あたりの平均学習時間:9.4h
今日までに到達すべき目標時間:1005h
目標との解離:25h
「10,000時間」まで、
残り・・・「8970時間!」