Strong Parameters [Rails 4 Countdown to 2013]

Posted on

This post is part of a series of 31 Rails 4 articles being released each day in December 2012.

In Rails 3.x, all model attributes are protected by default. They are only available for mass assignment if you specifically set them as attr_accessible.

In Rails 4, a new pattern has been introduced to secure your models from mass assignment. You can filter the parameters passed to your model in the controller instead of whitelisting attributes in your model using attr_accessible.

Behind the scenes

The parameters hash in your controllers is an instance of ActionController::Parameters. When this parameters hash is used to mass assign attributes in your models, ActiveModel will check if the hash is permitted?. The permitted attribute is false by default. You can set it to true using either permit!, or permits.

ActionController::Parameters comes with two very useful methods:

  • require(key): Fetches the key out of the hash and raises a ActionController::ParameterMissing error if it's missing.
  • permit(keys): Selects only the passed keys out of the parameters hash, and sets the permitted attribute to true.

Example:

Before

Here is an example of how you would allow mass assignment of name and age for a Person model in Rails 3:

class PeopleController < ApplicationController
  ...
  def create
    @person = Person.create(params[:person])
    ...
  end
  ...
end

You would have to whitelist both :name and :age in your model using attr_accessible:

class Person < ActiveRecord::Base
  attr_accessible :name, :age
end

After

In Rails 4, you don't need to whitelist attributes in your model anymore. In your controller you can filter the params as you see fit:

class PeopleController < ApplicationController
  ...
  def create
    @person = Person.create(person_params)
    ...
  end
  ...
  private
    def person_params
      params.require(:person).permit(:name, :age)
    end
end

Upgrade Path:

The Rails core team has released a gem strong_parameters, which allows you to use this functionality in your Rails applications today. To prepare your existing Rails 3 applications for strong parameters, perform the following:

  1. Add the strong_parameters gem to your Gemfile.
  2. Set config.active_record.whitelist_attributes to false in your application.rb.
  3. Add include ActiveModel::ForbiddenAttributesProtection to your models.
  4. Update your controllers to filter the params to your needs, for example: params.require(:person).permit(:name, :age).

Once Rails 4 is out, you can simply undo the first three steps and you're ready to go.

Further Reading

Rida

This post is by Rida Al Barazi. Rida is a passionate web developer experienced in building web applications for startups. He started working with Rails in 2005, co-authored Beginning Rails 3, and has spoken at conferences around the world.


Comments

comments powered by Disqus