How to Upgrade to Strong Parameters in Rails
This article was originally published in the blog of ActBlue Technical Services.
In the previous blog post, using a series of tests, we described how strong parameters work. In this post we detail the steps we followed to upgrade our main application in ActBlue.
Starting Point
To help with the process Rails provides the protected_attributes
gem. This allows you to run your app on 4.1 without having to make any changes related to mass-assignment protection. The gem brings backwards compatibility by implementing attr_accessible
, attr_protected
and other methods.
Add these lines to your Gemfile, run bundle install
and make all your tests pass (you have tests, right?)
gem 'rails', '~> 4.1' gem 'protected_attributes'
There are other incompatibilities you will have to resolve, but this post is about strong parameters and we are assuming your tests run green at this point.
Mixing Both
It is unlikely you can make all the changes in a single release and therefore you will want to have both protected attributes and strong parameters working at the same time. So the next step is to add this line to Gemfile and run bundle install
:
gem 'strong_parameters'
In every model you want to upgrade add this line to include the ForbiddenAttributesProtection
module. This is the way to indicate Rails which models are using the new mechanism, for example:
class Book < ActiveRecord::Base include ActiveModel::ForbiddenAttributesProtection end
In the model also remove all calls to attr_accessible
and attr_protected
, for example:
attr_accessible :isbn, :title attr_protected :price
In the corresponding controller it is useful to create a private method that whitelists its parameters, for instance:
private def book_params params.require(:book).permit(:isbn, :title) end
For simple models and controllers it is going to be similar to this, but for more complex cases you can check our previous blog post or the documentation.
Dropping Protected Attributes
When you think you have upgraded all your models and controllers and feel you are ready to pull the plug on the old protected attributes, these are the steps we recommend:
Remove these 2 lines from Gemfile and run bundle install
.
gem 'protected_attributes' gem 'strong_parameters'
In Rails 4 the default is strong parameters, so there is no need to include the gem.
Remove the configuration for protected_attributes, this means removing from config/application.rb:
config.active_record.whitelist_attributes = false
Remove from config/environments/test.rb:
config.active_record.mass_assignment_sanitizer = :logger
Remove any include ActiveModel::ForbiddenAttributesProtection
from models, added in the previous step.
In the default configuration of strong parameters, when you whitelist only a subset of the params passed to the controller, instead of raising an exception, Rails is going to generate a notification. You can see a test illustrating this.
It is better instead to always raise an exception. This is done by adding this line to config/environments/test.rb:
config.action_controller.action_on_unpermitted_parameters = :raise
Now run all your tests. If you have a large application and you are getting errors you do not understand or the code is not behaving the way you expect, check our previous blog post Understanding Strong Parameters, this is the part where this information is most useful.
Final Step
When you are done with the tests you can remove the line from config/environments/test.rb:
config.action_controller.action_on_unpermitted_parameters = :raise
The default value in Rails is to generate a notification in test and development environments, and ignore otherwise.
You are done! We hope the 2 articles helped you to make the transition smoother.