[rails]Strong Parametersでhashを許可する場合のやり方
Rails4.1.7, Ruby2.1.4 で確認。
Rails4より導入されたMass Assignment脆弱性を防ぐための仕組みがStrong Parametersです。
def create
@user = User.new(permitted_params)
end
private
def permitted_params
params.permit(:name, :email)
end
こんな感じでコントローラで許可したパラメータのみをmodelに渡すことができます。
なお、許可されていないパラメータを渡した場合は無視されます。
(例外を投げるように変更することも可能) このStrong Parametersでhashを許可する場合、2通りのやり方がありました。
例として
location = { x: 10, y: 20 }
というhashをパラメータとして送った場合、
1. hashの内容も厳密にチェックする場合
def permitted_params
params.permit(:name, :email, location: [:x, :y])
end
というようにlocationをキーにして、許可するパラメータ(x, y)のシンボルを配列に記述します。
この場合は、新たにzキーを追加して
location = { x: 10, y: 20, z: 30 }
としてリクエストを行っても、zの値は無視されてしまうので注意が必要です。
p permitted_params[:location]
=> {"x"=>10, "y"=>10}
2. hashであれば内容自体はチェックしない場合
hashではあるけどhashのキーに何がくるかは厳密にチェックしなくてもいい、という場合はホワイトリストに追加することで対応できました。
def permitted_params
params.permit(:name, :email).tap do |whitelisted|
whitelisted[:location] = params[:location] if params[:location].is_a?(Hash)
end
end
Object#.is_a?(Hash) でhashかどうかのチェックをして、hashだったらそのまま許可しています。
この場合は、新たにzキーを追加して
location = { x: 10, y: 20, z: 30 }
としてリクエストを行った場合は、zの値も取得できます。
p permitted_params[:location]
=> {"x"=>10, "y"=>10, "z"=>30}
以上、Strong Parametersでhashを許可する場合のやり方でした。