はじめに
Railsで「1つのフォームから複数のモデルに対して更新する処理」を作っていた時に結構苦戦したので、今回メモとして残していこうと思います。
もし誰かの参考になりましたら、幸いです。
使用する環境
- MacOS(M1)
- Rails 6.1.4
- Ruby 2.6.3
- yarn 1.22.17
- Homebrew 3.5.0
コードの解説
今回の実装のポイントとしては2つあります。
1つ目は
「ネストされて送られてくるパラメーターを、ストロングパラメータで上手く受け取ってあげる」ということです。
下記のようにViewから送られてくる場合
#<ActionController::Parameters {"_method"=>"patch", "user"=>{"name"=>"hoge", "email"=>"", "profile_attributes"=>{"gender"=>"man", "weight"=>"60.0", "id"=>"12"}}, "commit"=>"更新", "controller"=>"users/registrations", "action"=>"update"} permitted: false>
users_controller.rb
# ネストされてるパラメーターを許可する
def profile_params
params.permit(user: {profile_attributes: [:gender, :weight]})
end
2つ目は
「ネストされて送られてきたパラメーターを作成・更新時に上手く取り出してあげる」ということです。
下記のような形に取り出して更新しないとエラーが出ます。
#<ActionController::Parameters {"gender"=>"woman", "weight"=>"89.0"} permitted: true>
エラー内容
ActiveRecord::AssociationTypeMismatch: expected, got Fixnum
修正後
users_controller.rb
def update
@current_user_profile = current_user.profile
@current_user_profile.update!(profile_params[:user][:profile_attributes])# 上手くネストされたパラメーターからprofileの内容だけ取得する
end
参考:https://kyohei8.hatenablog.com/entry/2013/04/25/115002
最後に
ちょっと自分用のメモのため少し雑になって、上手く説明できなかったところもあるかもしれませんが、少しでもお役になったら幸いです