I'm trying to update to Rails 5, I'm getting the following deprecation warning:
DEPRECATION WARNING: Method to_hash is deprecated and will be removed in Rails 5.1, as
ActionController::Parameters
no longer inherits from hash. Using this deprecated behavior exposes potential security problems. If you continue to use this method you may be creating a security vulnerability in your app that can be exploited. Instead, consider using one of these documented methods which are not deprecated: http://api.rubyonrails.org/v5.0.0/classes/ActionController/Parameters.html (called from column_header at /Data/Projects/portal/trunk/app/helpers/application_helper.rb:114)
The line the warning is on looks like this:
link_to(name,
{
action: action_name,
params: params.merge({ order: key, page: nil })
},
{
title: "Sort by this field",
}) +
As you can see, I'm not calling to_hash
. Maybe Rails is. Maybe some other gem is. I have no way to tell, because they didn't think it was worth providing a stack trace. (Pro tip - it usually is worth providing a stack trace!)
So anyway, I followed the link, planning to find a replacement, and the merge
method does not appear to be deprecated, but maybe they simply forgot to document deprecated status, so I can't really be sure.
So what am I supposed to do to clear this?
.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:
.permit
to whitelist the values you expect.to_h
to ensure that if you forgot step 1, nothing will get through.permit
and call .to_unsafe_hash
.to_hash
because that's now ambiguousIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With