0

After updating some 15-20 entries of my new database I realized my data wasn't updated. I just read about the strong parameters in Rails 4.0 and it turned out that I hadn't whitelisted them. I understand the reason for having them (although I completely disagree of the workflow it creates).

Basically, my workflow while creating an app is that I create a scaffold Model with some attributes. I typically need to update (add to) this model as I realize new attributes are needed. I do this using migrations like:

rails g migration AddThisNewAttributeToProduct this_new_attribute:string

But I learned today that by doing so, this is not automatically added to the strong parameters list and basically if I use it in a form, it will not be saved to the database. What the worst part is, is that I don't get any warning or anything!

Since I will be quite likely to forget to update the strong parameters list when I add parameters in the future I will end up doing this over and over (i.e. trying to alter data using the forms without it being saved to the database).

So, I am quite puzzled about how to solve this:

  1. Is there a way to, while using a migration to add attributes to a model, automatically add the attribute to the strong parameter list?

  2. Is there a way to disable the strong parameter white list in development mode?

  3. Could it be disabled while logged in into an admin?

  4. (IMPORTANT) Could I, at least, make the app crash if I try to alter an attribute that is not in the whitelist? So I get reminded to add it? Pretty much the way attr_accessible used to work.

Christoffer
  • 2,271
  • 3
  • 26
  • 57
  • you would definitely get a warning, `Unpermitted parameters: blah-blah` in the logs when you pass a field `blah-blah` from `form` and have not whitelisted it in controller. – Kirti Thorat May 07 '14 at 18:04
  • That's weird, I thought that would get an `ActiveModel::ForbiddenAttributesError` error when trying to create a record with mass assignment with an attribute that hasn't been whitelisted. edit: actually, that's when you dont permit any I think, otherwise, as Kirti said, you will get `Unpermitted parameters: password` for instance. – Robin May 07 '14 at 18:04
  • If you **really** want to you can whitelist the entire hash of parameters with `params.require(:product).permit!` but you should be very sure you want to do this. Personally I would not recommend this and consider it a part of acceptance testing to ensure new/amended data on the form is being created/updated correctly. –  May 07 '14 at 18:23
  • Graeme, that actually worked! This will be great to do during development and then I can fix it for the production. It will make things a lot easier. Thanks! – Christoffer May 08 '14 at 05:10

2 Answers2

1

1. Is there a way to, while using a migration to add attributes to a model, automatically add the attribute to the strong parameter list?

No. They would only be added automatically for you in case you generate scaffold.

2. Is there a way to disable the strong parameter white list in development mode?

No. You cannot disable it. And it's a good thing, you really don't want to do that. It is beneficial to fight against mass assignment vulnerabilities.

3. Could it be disabled while logged in into an admin?

No. Read my comments on #2.

4. (IMPORTANT) Could I, at least, make the app crash if I try to alter an attribute that is not in the whitelist? So I get reminded to add it? Pretty much the way attr_accessible used to work.

You most definitely get a warning, Unpermitted parameters: blah_blah in the logs when you pass a field blah_blah from form and have not whitelisted it in controller.

You can even check the queries generated while creating/ updating records for the create and update actions respectively to see which fields were actually saved in the database and which ones were missed.

The logs would be available on the terminal where you are running rails server. You can find them in environment specific log files placed in application_folder/log directory. So, if you are in development you can check development.rb in the log directory.

Kirti Thorat
  • 52,578
  • 9
  • 101
  • 108
  • This really sucks. I mean, I know it is a safety issue but not being able to disable it in development mode doesn't make any sense. If I am creating an app on my laptop and is using forms to update models through the edit-functionality there is NO risk at all and it should be possible to disable! – Christoffer May 07 '14 at 21:08
  • My second thought is what kind of workflow does everyone else have in order to update the data. I mean, if you add an attribute/column in a migration, what is the reason NOT to include it in the whitelist? Warnings doesn't really help me much since if I won't remember to add a newly added attribute to the whitelist I won't remember to double-check the log when I do updates either. – Christoffer May 07 '14 at 21:13
  • Lastly, I forgot to say Thanks for your clear answer! And by the way, is it possible to catch this Warning and make the app crash (so I'll notice it?) when it occurs? – Christoffer May 07 '14 at 21:13
0
  1. No, rails migration will not do that. The best bet would be to write a script that does this for you but it's noth worth the effort.

  2. General rule of thumb is keep dev env as similar as prod env, so this is a bad idea. In theory, you can use some conditional to check Rails.env == "production" and Rails.env == "development" to run one piece of code using strong param in prod and using Rail3 way of writing attributes after attr_accessible, but then again, this will end up monstrously ugly code.

  3. This isn't related to whether a person is logged in as an admin or not.

  4. You get Unpermitted parameters: attr_name in your log when you try to save some attribute that's not listed in the strong param.

Jason Kim
  • 18,102
  • 13
  • 66
  • 105