Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
368 views
in Technique[技术] by (71.8m points)

ruby on rails - What is the difference between attr_accessible(*attributes) & attr_protected(*attributes)?

What is the difference between attr_accessible(*attributes) & attr_protected(*attributes)? Examples would be nice.

I see many developers use these in their models. I googled for the differences, but I don't get exactly what they are. What is the importance and its necessity in different scenarios?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.)

A 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). The behaviour upon an attempt to update a protected attribute via mass assignment depends on the mass_assignment_sanitizer setting (see the update below).

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

Update: Later versions of Rails introduced the concept of a mass assignment sanitizer to control the behaviour upon attempts to update protected attributes via mass assignment. In Rails 3.2 and later this can be controlled by setting mass_assignment_sanitizer in config. The default is to just log the attempts and allow code execution to continue, but the standard environment config for development sets this to :strict which raises as exception on an attempt to update a protected attribute.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...