attr_accessible(*attributes)和attr_protected(*attributes)之间有什么区别?

Sal*_*lil 35 activerecord ruby-on-rails

attr_accessible(*attributes)attr_protected(*attributes)?有什么区别?例子很好.

我看到很多开发人员在他们的模型中使用它们 我搜索了差异,但我不确切地知道它们是什么.在不同情况下,重要性及其必要性是什么?

mik*_*kej 99

attr_accessible(文档)说"指定的属性是可访问的,所有其他属性都受到保护"(将其视为白名单.)

attr_protected(文档)说"指定的属性受到保护,其他所有属性都可以访问"(将其视为黑名单.)

保护属性是一个只能被显式修改(例如,经由属性=),并且不能经由质量分配(例如,使用更新model.update_attributes或通过传递属性new).尝试通过批量分配更新受保护属性时的行为取决于mass_assignment_sanitizer设置(请参阅下面的更新).

经典示例是,如果User模型具有is_admin可以保护该属性的属性,以防止允许将任何用户设置为管理员的表单提交.

例:

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
Run Code Online (Sandbox Code Playgroud)

和....相比:

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
Run Code Online (Sandbox Code Playgroud)

现在,假设is_admin属性受到保护:

> 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
Run Code Online (Sandbox Code Playgroud)

更新:Rails的更高版本引入了质量分配清理程序的概念,以控制尝试通过批量分配更新受保护属性时的行为.在Rails 3.2及更高版本中,可以通过mass_assignment_sanitizer在config中设置来控制.默认情况下,只记录尝试并允许代码执行继续,但开发的标准环境配置将此设置:strict为尝试更新受保护属性时引发的异常.

  • 不,你只能使用其中一个.如果你在一个类中包含这两个,那么在第一次加载类时你不会看到错误但它可能会表现为"NoMethodError:当你没有想到它时你有一个nil对象!"当你尝试使用时班级. (4认同)

gre*_*gor 7

attr_accessible是一个用于批量分配的白名单......

class Foo < ActiveRecord::Base #has attributes foo and bar
  attr_accessible :foo
end
f = Foo.new :foo => "test", :bar => "test"
f.foo #=> "test"
f.bar #=> nil
Run Code Online (Sandbox Code Playgroud)

attr_proteceted是一个黑名单,用于大规模分配......

class Foo < ActiveRecord::Base #has attributes foo and bar
  attr_protected :bar
end
f = Foo.new :foo => "test", :bar => "test"
f.foo #=> "test"
f.bar #=> nil
Run Code Online (Sandbox Code Playgroud)