📑
ActionController::Parameters#to_h は permit した属性がないとエラーになる
知らなかったので覚書。
ActionController::Parameters#to_h
は通常 permit
された属性のみを含んだ Hash を返します。
require "action_controller"
params = ActionController::Parameters.new({
name: "Senjougahara Hitagi",
oddity: "Heavy stone crab"
})
# name のみを許可する
safe_params = params.permit(:name)
# to_h では許可された属性のみを Hash に変換する
p safe_params.to_h
# => {"name"=>"Senjougahara Hitagi"}
しかし、逆に permit
された属性がない場合に #to_h
を呼び出すとエラーになります。
require "action_controller"
params = ActionController::Parameters.new({
name: "Senjougahara Hitagi",
oddity: "Heavy stone crab"
})
# error: unable to convert unpermitted parameters to hash (ActionController::UnfilteredParameters)
p params.to_h
こんな感じで permit
された属性がない場合は利用を禁止しているみたいですね。
コード上で #to_h
を利用する場合は permit
されているかどうかで挙動が変わりので注意が必要そうです。
#to_h
の戻り値
おまけ #to_h
メソッドの戻り値なんですが厳密にいうと Hash
ではなくて ActiveSupport::HashWithIndifferentAccess
を返します。
require "action_controller"
params = ActionController::Parameters.new({
name: "Senjougahara Hitagi",
oddity: "Heavy stone crab"
})
# name のみを許可する
safe_params = params.permit(:name)
# Hash ではなくて ActiveSupport::HashWithIndifferentAccess を返す
p safe_params.to_h.class
# => ActiveSupport::HashWithIndifferentAccess
# なので String でも Symbol でもアクセスできたりする
p safe_params.to_h["name"] # => "Senjougahara Hitagi"
p safe_params.to_h[:name] # => "Senjougahara Hitagi"
Hash
だと思っていると結構ぎょっとする挙動ですねー。
ちなみに #to_hash
だと Hash
が返ってきます。
require "action_controller"
params = ActionController::Parameters.new({
name: "Senjougahara Hitagi",
oddity: "Heavy stone crab"
})
# name のみを許可する
safe_params = params.permit(:name)
p safe_params.to_hash.class
# => Hash
Discussion