LoginSignup
6
3

More than 5 years have passed since last update.

ポリモーフィック関連のモデルがある場合のフォーム作成

Last updated at Posted at 2018-02-26

関係:
User > memo

ハマりポイント:

  • ビューとストロングパラメーターをどう書くか
  • accepts_nested_attributes_forを使用する場合inverse_of を記載しないとうまく動かない(バリデーションエラー?になる)
    • バリデーションエラーとしたのは @user.error.fullmessagesで Memos memoable must existとなるから

accepts_nested_attributes_forを使用しない場合

ネストとか考えなくていいので楽といえば楽。モデルの記述もシンプル。
ポリモーフィック関連のある子要素がhas_manyなのかhas_oneなのかで以下の記載を書き換え

  • モデルの has_many :複数形 / has_one :単数形 記述
  • controllerで用意するインスタンス @user.memos.build (複数形)/ @user.build_memo(単数形)
memo.rb
class Memo < ApplicationRecord
  belongs_to :memoable, polymorphic: true
end
user.rb
class User < ApplicationRecord
  has_one :memo, as: :memoable
end
user.controller.rb
  def new
    @user = User.new
    @user.build_memo
  end

  def create
    @user = User.new(user_params)
    @user.build_memo(memo_params)

    @user.save
  end
:

  private

    def user_params
      params.require(:user).permit(:name)
    end

    def memo_params
      params.require(:memo).permit(:body)
    end

※ストロングパラメーターは個別に分けて記述
※子要素を作成する際にアソシエーションを利用しているので、 memoable_idとmemoable_typeは記述しなくても自動で補填された

<%= form_for @user do |form| %>
    <%= form.label :name %>
    <%= form.text_field :name, id: :user_name %>

  <%= fields_for :memo do |field|%>
    <%= field.label :body %>
    <%= field.text_field :body %>
  <% end %>

    <%= form.submit %>
<% end %>

※ fields_forはform_forにネストさせない形で記載

accepts_nested_attributes_forを使用する場合

user.rb
class User < ApplicationRecord
  has_many :memos, as: :memoable, inverse_of: :memoable
  accepts_nested_attributes_for :memos
end
memo.rb
class Memo < ApplicationRecord
  belongs_to :memoable, polymorphic: true, inverse_of: :memoable
end
users_controller.rb
  def new
    @user = User.new
    @user.memos.build
  end

  def create
    @user = User.new(user_params)
    @user.save
  end
:
 private
    def user_params
      params.require(:user).permit(:name,memos_attributes:[:body])
    end

※newに@user.memos.buildを記載していないとフォームが表示されない注意

<%= form_for user do |form| %>
    <%= form.label :name %>
    <%= form.text_field :name, id: :user_name %>

  <%= form.fields_for :memos do |field|%>
    <%= field.label :body %>
    <%= field.text_field :body %>
  <% end %>

    <%= form.submit %>
<% end %>

※ fields_forはform_forにネストさせて記載

userモデルを削除した際に関連したmemoモデルも削除する場合は以下を追記

user.rb
class User < ApplicationRecord
  has_many :memos, as: :memoable, inverse_of: :memoable, dependent: :destroy
  accepts_nested_attributes_for :memos
end
users_controller.rb
 private
    def user_params
      params.require(:user).permit(:name,memos_attributes:[:body,:id,:_destroy])
    end
6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3