Jason
Jason

Reputation: 2743

How does Rails know the difference between these two identical expressions?

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

Answers (1)

TDJoe
TDJoe

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

Related Questions