railsのparams permitすると変更できなくなる
結論から言え!
railsのstrong parameterでpermitしたhashは変更できない
railsのstrong parameter
railsにはstrong parameterと言う機能があります
簡単に説明すると、明示的に許可したparameterのみobjectに渡す仕組みです
railsを書いたことある方なら誰でも一度は使ってるんじゃないでしょうか
下のように主にcontrollerの中で使います
# users_controller.rb ... ... def show @user = user_params end ... ... private def user_params params.require(:user).permit(:name, :age) end
user_paramsメソッドの中でrequireでオブジェクト名を決めてpermitで許可するkey名を指定しています
permitされた値に変更を加えたい
先日、このようにして許可した値に変更を加えたい状況になりました
以下のようにして変更を加えようとしました
# users_controller.rb ... ... def show user_params[:age] += 20 # user_paramsで取得したageに20を加える @user = user_params end ... ... private def user_params params.require(:user).permit(:name, :age) end
しかしuser_paramsを表示してみると変更前の値になっていました
permitで返しているのは新しいobject
調べていると下の記事を見つけました
permit returns a new hash with those keys in it, so you're not modifying the real params variable.
permitは許可したkeyを持つ新しいオブジェクトを返すので、元のparameterを変更することはできない
まじか!と思いpermitの定義をみてみると
def permit(*filters) params = self.class.new ...
まじだ!!!
と言うことでparamsを直接変更しようとしてもうまくいきません
諦めて別のhashを作成してそれを渡して解決しました
# users_controller.rb ... ... def show new_params = user_params new_params[:age] += 20 # user_paramsから作ったnew_paramsのageに20を加える @user = new_params end ... ... private def user_params params.require(:user).permit(:name, :age) end
知らないところで思ってもない処理がされてるもんですね
参考
Strong Parameters in Rails —down the rabbit hole - Tomer Brisker - Medium
Modify ruby hash in place( rails strong params) - Stack Overflow
Modifying strong parameter values after a request | Development Simplified