17

This video states that it is possible to protect the input coming in via the controller yet still be able to do mass assignment via models and specs. However, I have not seen this documented as a feature when using strong_parameters in 3.2.8.

I understand that I need to mix in ActiveModel::ForbiddenAttributesProtection into my models and set config.active_record.whitelist_attributes = false in config/application.rb. I have also pulled all of my attr_accessible calls from the model.

With or without the mixin I am getting mass assignment errors.

ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes: home_phone, cell_phone

Am I missing something?

Brandon Hansen
  • 816
  • 1
  • 10
  • 17

2 Answers2

23

The suggested RailsCast is probably a good start, but here is a summary of what you have to do in Rails 3.x to get strong parameters working instead of attr_accessible:

  1. Add gem 'strong_parameters' to your Gemfile and run bundle.

  2. Comment out (or set to false) config.active_record.whitelist_attributes = true in config/application.rb

  3. Mix in the ActiveModel::ForbiddenAttributesProtection in your model. Do this per model, or apply globally to all models with:

    ActiveRecord::Base.send(:include, ActiveModel::ForbiddenAttributesProtection)

    (The railscast proposes to do this in a new initializer: config/initializers/strong_parameters.rb )

  4. From now on you will have to use syntax such as this:

    model_params = params[:model].permit( :attribute, :another_attribute )
    @model.update_attributes( model_params )
    

    when you update your models. In this case any attribute in params[:model] except :attribute and :another_attribute will cause an ActiveModel::ForbiddenAttributes error.

You can also use the rest of the new magic from ActionController::Parameters, such as .require(:attribute) to force the presence of an attribute.

David Hempy
  • 5,373
  • 2
  • 40
  • 68
2

It isn't the same as your issue but it may come up for someone else getting MassAssignmentSecurity::Error. I've hit an issue that 'id' and 'type' attributes seem to be protected by default even when I had taken the prescribed steps to switch to using strong parameters rather than mass assignment protection. I had an association named 'type' which I renamed to 'project_type' to resolve the problem (the attribute was already project_type_id).

Joseph Lord
  • 6,446
  • 1
  • 28
  • 32
  • Using `type` for attributes or relations is a bad idea since Rails uses that to keep track of STI relations. So it's more or less a reserved attribute :) Also `id` is the default param that gets set in a number of cases by the router so that might be precarious to use as well. – Jonas Schubert Erlandsson Apr 08 '13 at 13:34
  • @d-Pixie Fair enough but the errors I got were really not helpful and very confusing. An error saying not to use those would be fine, an MassAssignmentSecurity::Error when that whole system was meant to be disabled was very confusing. type was the one that I hit and I found id was also affected when I dug into the sourcecode. – Joseph Lord Jun 28 '13 at 21:20
  • Ran in to the same problem, error is not descriptive. Use `self.inheritance_column = nil` to fix if you're not using STI. – toxaq Dec 06 '14 at 00:31