Before going into the details of attr_accessible, the best thing would be to understand why it was needed.
It was basically needed to avoid the Mass-assignment Attack.
For that we need to know about Mass-assignment :-
Mass-assignment is used to assign values to multiple attributes of a model in one go. Let's assume we have a Person model with (name, age, home_town and zip) attributes. admin is another attribute which is boolean in type, it tells whether the person is admin or not.
Now we can use mass-assignment like:-
params[:person] = {:name => 'taran', :age => 25, :home_town => 'Dehradun'}
And then we can create a new Person object as :-
@person = Person.new(params[:person])
With this approach each & every value need not to be set up individually.
Now the problem with this Mass-Assignment is that we are letting the user set up all the attributes, thus now he can hack into the code by setting the 'admin' attribute as 'true' to gain all the permissions.
Example:-
http://localhost:3003/person/signup?person[name]=taran&person[age]=25&person[home_town]=Dehradun&person[admin]=1
Now in rails we can avoid this in following ways:-
--> attr_protected
through this we can specify a particular attribute to not be the part of mass assignment.
Example:-
class Person < ActiveRecord::Base
attr_protected : admin
end
--> Other way is to set each and every attribute of all the models as un-accessible. For this in config/application.rb we set
config.active_record.whitelist_attributes = true
and then in a particular model we specify which attribute we want to be available for mass_assignment.
class Person < ActiveRecord::Base
attr_accessible : name
end
"attr_accessible" is the Rails way of specifying a particular model's attributes that are permitted for mass-assignment. Its behaviour is inverse of "attr_protected" macro which prevents a particular attribute from mass-assignment.
In this way mass-assignment will only permit those attributes which are permitted using "attr_accessible", if we wish to assign some other attribute we have to use direct writer methods.
For example :-,
to identify the Person models name, age, home_town and zip attributes as mass-assignable, we will set attr_accessible in the Person model as follows:
class Person
attr_accessible :name, :age, :home_town, :zip
end
now with the attr_accessible set like this, we can easily mass-assign the above 4 attributes as:
person = Person.new(
:name => 'Taranjeet Singh',
:age => 25,
:home_town => 'Dehradun',
:zip => '248001')
In Rails 4 this problem of Mass-assignment Vulnerability was solved by the use of Strong Parameters. Rails 4 depreciated the "attr_accessible" and "attr_protected". With this the burden of filtering the params has been moved to the controller, rather than whitelisting them within the model.
To use strong params we typically define a private method in the desired controller.
class PersonController < ActionController::Base
def create
@person = Person.create(person_params)
end
def update
person = Person.find(params[:id])
person = Person.update_attributes!(person_params)
redirect_to person
end
private
def person_params
params.require(:person).permit(:name, :age, :home_town, :zip)
end
end
The above private method named person_params will only permit the "name","age","home_town" and "zip" parameters for the "person" params
0 Comment(s)