How to Upgrade to Strong Parameters in Rails

December 10, 2014

This article was originally published in the blog of ActBlue Technical Services.

How to Upgrade to Strong Parameters in Rails

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.