💎
【Rails】nested attributesのstrong parametersにmerge
基本:ActionController::Parametersにmerge
例えば、フォームからはタイトルと本文だけPOSTして、ログインユーザーのIDはサーバーサイドでセットするような場合、コントローラーのストロングパラメータを以下のような記述にすると
private
def article_params
params.require(:article).permit(:title, :body)
.merge(user_id: current_user.id)
end
パラメータにユーザーIDがセットされます。
{"title"=>'タイトル', "body"=>"本文", "user_id"=>1}
子レコード(nested nestedがある場合)
今度はaccepts_nested_attributes_for
を利用して子レコードを一気に保存する場合で、子レコードの方にuser_idをmergeしたい。
以下のように書くといけました。
articleに対してcommentがhas_manyで紐づいている関係です(この例だとarticleを書きつつcommentを自作自演しているみたいになっていて実際のフォームとしては妙ですが)。
def article_params
params.require(:article).permit(:title, :body, comments_attributes: [:body])
.tap do |p|
p[:comments_attributes].each do |k, hash|
hash.merge!(
user_id: current_user.id,
)
end
end
end
これでストロングパラメータが以下の形になります。
{"title"=>'タイトル', "body"=>"本文", "messages_attributes"=>{"1"=>{"body"=>"本文", "user_id"=>1}}}
ちなみにtapは初知りでした。リファレンスによれば「self を引数としてブロックを評価し、self を返します。」とのことで、もともとはメソッドチェーン内で途中経過のデバッグ目的で作られたものらしいですが、色々と裏技的な使い方があるようです。
備考
環境
Ruby 3.2
Rails 7.0
参考
こちらを参考にしたのですがそのまま真似してもうまくいかなかったです
Discussion