attr_accessible and attr_protected in the Model

This is a word for word copy-paste from an answer to a question on StackOverflow. The first time I had issues with attr_accessible (which was the fact that I was missing the mass assignment bit), my thoughts were quelled by this excellent explanation. I just came across it accidentally today and thought that I should post it here.. even for my own sake.

Source: http://stackoverflow.com/questions/2652907/what-is-difference-between-attr-accessibleattributes-attr-protectedattrib

 

attr_accessible (documentation) says “the specified attributes are accessible and all others are protected” (think of it as whitelisting.)

whereas

attr_protected (documentation) says “the specified attributes are protected and all others are accessible” (think of it as blacklisting.)

protected attribute is one that can only be modified explicitly (e.g. via attribute=) and can’t be updated via mass assignment (e.g. using model.update_attributes or by passing attributes to new). Attempts to update protected attributes via mass assignment are silently ignored without raising an exception.

The classic example would be if a User model had an is_admin attribute you could protect that attribute to prevent form submissions that would allow any user to be set as an administrator.

Example:

class User < ActiveRecord::Base
# explicitly protect is_admin, any new attributes added to the model
# in future will be unprotected so we need to remember to come back
# and add any other sensitive attributes here in the future
attr_protected :is_admin
end

compared with:

class User < ActiveRecord::Base
# explicitly unprotect name and bio, any new attributes added to the model
# in the future will need to be listed here if we want them to be accessible
attr_accessible :name, :bio
end

Now, assuming is_admin attribute is protected:

> u = User.find_by_name('mikej')
> u.is_admin?
false
> u.update_attributes(:name => 'new name', :is_admin => true)
> u.is_admin?
false
> u.name
"new name" 
> u.is_admin = true # setting it explicitly
> u.save
> u.is_admin?
true









1 Comment

Did this waste your time or did you benefit from it? Let me know :-) Feel free to add your own views too