📝

Railsストロングパラメータの罠:直接の変更は反映されない?

2023/11/10に公開

railsのストロングパラメータは、コントローラーでのパラメータのハンドリングを強力にし、セキュリティを向上させる仕組みです。しかしながら、直感に反して、ストロングパラメータを通過した後にパラメータを変更しようとしたらうまくいかず「あれ?」となったことがあったので共有します。

たとえば、ユーザーの名前を更新しようと以下のようにコードを書いたとします。

params.require(:user).permit(:name, :email)
params[:user][:name] = '新しい名前' # この行では意図した変更を試みています。

このコードを実行しても、変更は次回の params[:user] の呼び出しで反映されませんでした。これは、permit メソッドが呼ばれるたびに新しい ActionController::Parameters オブジェクトを返しすためです。

その前に変更を行ったparamsとは違うオブジェクトのため、前回の変更を「記憶」していないといことのようです。

この問題を解決するために、私は次のように変数にストロングパラメータの結果を格納し、その変数を介して値の変更を行いました。

user_params = params.require(:user).permit(:name, :email)
user_params[:name] = '新しい名前' # 変更はこの変数に保持されます。

この方法で、変更は期待通りに保持されました。ActionController::Parametersがイミュータブルな性質を持っているなんて私は知りませんでした。

この記事が、同じような問題に直面した開発者の助けになることを願っています!

Discussion