Reputation: 2743
I am using a 4-year old Rails tutorial and I have Rails 4.0.2. I made a model called "Thing" and a controller called "Things". The "Thing" model has one attribute called "data". In my create
action, I had this line:
@thing = Thing.new(params[:thing])
which results in this error:
ActiveModel::ForbiddenAttributesError in ThingsController#create
I found a StackOverflow thread that said I needed to require
my needed parameters, and that worked just fine.
Before I looked that up I tried putting the hash from my params directly into the Thing.new()
method and I didn't get an error. I started with this line:
puts params[:thing]
in my create
action, typed "12345" in my text field, hit submit and got this in the console:
{"data"=>"12345"}
So I tried this in the create
action:
@thing = Thing.new({"data" => "12345"})
and I didn't get the error. I even confirmed they were identical by doing this:
puts params[:thing] == {"data"=>"12345"}
and I get "true" on the console. So,
Thing.new(params[:thing])
gives me the error, but
Thing.new({"data"=>"12345"})
does not.
How can Rails tell the difference between these two arguments when they seem to be identical?
Upvotes: 3
Views: 114
Reputation: 1398
params[:thing]
is not the same thing as {"data" => "12345"}
, they just have the same value when inspect
is called on them, and params
's class overrides ==
to say it's equal to the hash.
Rails 4+ uses Strong Parameters, which is a security feature to make sure you know what you're putting in your models. Basically, Rails wants to you check the validity of the parameters. It lets you do Thing.new({"data" => "12345"})
because you, the developer, are creating the Hash directly, and are more trustworthy than someone on the internet calling your server.
Upvotes: 6