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?
Strong Parameters, aka Strong Params, are used in many Rails applications to increase the security of data sent through forms. Strong Params allow developers to specify in the controller which parameters are accepted and used.
Specifically, params refers to the parameters being passed to the controller via a GET or POST request. In a GET request, params get passed to the controller from the URL in the user's browser. For example, if our app's controller looked like. def show. @person = Person.find(params[:name])
Mass Assignment is the name Rails gives to the act of constructing your object with a parameters hash. It is "mass assignment" in that you are assigning multiple values to attributes via a single assignment operator.
It returns an instance of ActionController::Parameters for the key passed into require . The permit method returns a copy of the parameters object, returning only the permitted keys and values. When creating a new ActiveRecord model, only the permitted attributes are passed into the model.
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:
Add gem 'strong_parameters'
to your Gemfile and run bundle.
Comment out (or set to false) config.active_record.whitelist_attributes = true
in config/application.rb
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 )
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With