Use .to_h
You can call .to_h
to get a safe hash, according to a comment on the Rails PR.
There are now three methods for converting parameters to a hash.
.to_h
means "if I haven't called .permit
, assume nothing is allowed."
.to_unsafe_h
means "if I haven't called .permit
, assume everything is allowed."
.to_hash
is now ambiguous. Rails treats it like .to_unsafe_h
, but prints a warning because you haven't explicitly said which of the two options above you wanted.
First, let's see what happens if you haven't called .permit
. In a Rails 5.0 console:
> params = ActionController::Parameters.new({yes: "y", no: "n"})
> params.to_h
{} # empty hash because nothing has been permitted
> params.to_unsafe_h
{"yes"=>"y", "no"=>"n"} # raw values with no warning; you asked for it
> params.to_hash
# (puts deprecation warning - if you want unsafe values, say so)
{"yes"=>"y", "no"=>"n"} # returns raw values
However, if you call .permit
first, there will be no way to get the non-permitted values.
> params = ActionController::Parameters.new({yes: "y", no: "n"})
> params = params.permit(:yes)
# (puts warning about unpermitted parameter :no)
> params.to_h
{"yes"=>"y"} # permitted values only
> params.to_unsafe_h
{"yes"=>"y"} # permitted values only
> params.to_hash
# (puts deprecation warning, but still safe)
{"yes"=>"y"} # permitted values only
So:
- Always use
.permit
to whitelist the values you expect
- Use
.to_h
to ensure that if you forgot step 1, nothing will get through
- If you really want the raw values, don't call
.permit
and call .to_unsafe_hash
- Don't call
.to_hash
because that's now ambiguous
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…