関係:
User > memo
ハマりポイント:
- ビューとストロングパラメーターをどう書くか
- accepts_nested_attributes_forを使用する場合inverse_of を記載しないとうまく動かない(バリデーションエラー?になる)
- バリデーションエラーとしたのは @user.error.fullmessagesで
Memos memoable must exist
となるから
- バリデーションエラーとしたのは @user.error.fullmessagesで
###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