attr_accessor和attr_accessible之间的区别

在Rails中, attr_accessorattr_accessible什么attr_accessible ? 根据我的理解,使用attr_accessor可以为该variables创buildgetter和setter方法,以便我们可以访问像Object.variableObject.variable = some_value这样的variables。

我读到attr_accessible使外部世界可以访问的特定variables。 有人可以告诉我最新的差异

attr_accessor是一个使getter和setter成为可能的ruby方法。 attr_accessible是一个Rails方法,允许您将值传递给一个批量赋值: new(attrs)update_attributes(attrs)

这是一个大规模的任务:

 Order.new({ :type => 'Corn', :quantity => 6 }) 

您可以想象,订单也可能有折扣码,例如:price_off。 如果您不标记:price_off astr_accessible,则会阻止恶意代码执行下面的操作:

 Order.new({ :type => 'Corn', :quantity => 6, :price_off => 30 }) 

即使您的表单没有字段:price_off,如果它在您的模型中,则默认情况下是可用的。 这意味着制作的POST仍然可以设置它。 使用attr_accessible白色列出可以批量分配的东西。

很多人在这个线程和谷歌上解释得非常好, attr_accessible指定了允许批量更新的属性的白名单( 一个对象模型的所有属性同时在一起 )这主要(也是唯一的)保护你的应用程序从“大规模”海盗利用。

这里在官方Rails文档中解释: Mass Assignment

attr_accessor是一个ruby代码,用于(快速)在Class中创buildsetter和getter方法。 就这样。

现在,缺less一个解释是,当你创build一个带有数据库表的(Rails)模型之间的链接时,永远不要在你的模型中需要attr_accessor来创buildsetter和getters以便能够修改你的表的logging。

这是因为你的模型inheritance了ActiveRecord::Base Class中的所有方法,它已经为你定义了基本的CRUD访问器(Create,Read,Update,Delete)。 这是在官方的文档在这里解释Rails模型和这里覆盖默认访问器 (向下滚动到“覆盖默认访问器”一章)

比如说:我们有一个名为“users”的数据库表,它包含三列“firstname”,“lastname”和“role”:

SQL指令:

 CREATE TABLE users ( firstname string, lastname string role string ); 

我假设你在你的config / environment / production.rb中设置了config.active_record.whitelist_attributes = true这个选项来保护你的应用程序免受Mass assignment的攻击。 这里解释: 质量分配

您的Rails模型将完美地与下面的模型一起工作:

 class User < ActiveRecord::Base end 

但是,您需要分别更新控制器中用户的每个属性,以使表单的视图正常工作:

 def update @user = User.find_by_id(params[:id]) @user.firstname = params[:user][:firstname] @user.lastname = params[:user][:lastname] if @user.save # Use of I18 internationalization t method for the flash message flash[:success] = t('activerecord.successful.messages.updated', :model => User.model_name.human) end respond_with(@user) end 

现在为了减轻你的生活,你不想为你的用户模型制作一个复杂的控制器。 所以你将在你的Class模型中使用attr_accessible特殊方法:

 class User < ActiveRecord::Base attr_accessible :firstname, :lastname end 

所以你可以使用“高速公路”(集体作业)来更新:

 def update @user = User.find_by_id(params[:id]) if @user.update_attributes(params[:user]) # Use of I18 internationlization t method for the flash message flash[:success] = t('activerecord.successful.messages.updated', :model => User.model_name.human) end respond_with(@user) end 

您没有将“angular色”属性添加到attr_accessible列表中,因为您不让用户自己设置angular色(如admin)。 你可以在另一个特殊的pipe理视图上自己做。

尽pipe你的用户视图没有显示“angular色”字段,但是盗版者可以轻松地发送包含“angular色”的HTTP POST请求。 attr_accessible上缺less的“angular色”属性是为了保护你的应用程序。

你仍然可以像下面一样修改你自己的user.role属性,但是不能把所有的属性放在一起。

 @user.role = DEFAULT_ROLE 

为什么你会使用attr_accessor

那么,这将是在你的用户表单显示一个字段不存在于你的用户表中作为一列。

例如,假设你的用户视图显示“please-tell-the-admin-that-I'm-in-here”字段。 你不想把这个信息存储在你的表中。 你只是想让Rails给你发一封电子邮件,告诉你一个“疯狂”的用户已经订阅了。

为了能够使用这个信息,你需要将它暂时存储在某个地方。 在user.peekaboo属性中恢复它比什么更容易?

所以你把这个字段添加到你的模型中:

 class User < ActiveRecord::Base attr_accessible :firstname, :lastname attr_accessor :peekaboo end 

因此,您将能够熟练使用控制器某处的user.peekaboo属性来发送电子邮件或执行任何您想要的操作。

执行user.save时,ActiveRecord不会保存表中的“peekaboo”属性,因为她没有在模型中看到与该名称匹配的列。

attr_accessor是一个Ruby方法,它为setter和getter方法提供了一个同名的实例variables。 所以相当于

 class MyModel def my_variable @my_variable end def my_variable=(value) @my_variable = value end end 

attr_accessible是一个Rails方法,用于确定可以在批量分配中设置哪些variables。

当你提交一个表单,并且你有一些像MyModel.new params[:my_model]那么你想有一个更多的控制,让人们不能提交你不想要的东西。

你可能会做attr_accessible :email这样当有人更新他们的账户时,他们可以改变他们的电子邮件地址。 但是你不会做attr_accessible :email, :salary因为这样一个人可以通过表单提交来设置他们的工资。 换句话说,他们可以趁机加薪。

这种信息需要明确处理。 只是从表单中删除是不够的。 有人可以进入萤火虫,并将元素添加到表单提交工资领域。 他们可以使用内置的curl向控制器更新方法提交新薪水,他们可以创build一个脚本来提交一个包含该信息的post。

所以attr_accessor是关于创build方法来存储variables, attr_accessible关于质量分配的安全性。

attr_accessor是ruby代码,在数据库中没有列的情况下使用,但仍然希望在表单中显示一个字段。 唯一的方法是使用attr_accessor :fieldname ,如果需要,可以在视图或模型中使用这个字段,但大多数情况下是在你的视图中。

我们来看下面的例子

 class Address attr_reader :street attr_writer :street def initialize @street = "" end end 

这里我们使用了attr_reader可读属性 )和attr_writer可写属性 )来访问目的。 但是我们可以使用attr_accessor来实现相同的function。 简而言之, attr_accessor提供对getter和setter方法的访问。

所以修改后的代码如下

 class Address attr_accessor :street def initialize @street = "" end end 

attr_accessible允许你列出所有你想允许Mass Assignment的列。 与此相反的是attr_protected ,这意味着这个字段我不希望任何人被允许进行Mass Assign。 更不可能是你的数据库中的一个领域,你不希望任何人瞎猜。 像状态字段一样,

用两个字来说:

attr_accessorgettersetter方法。 而attr_accessible就是说特定的属性是可以访问的。 而已。


我想补充说,我们应该使用强参数,而不是attr_accessible来防止质量分配。

干杯!

一个快速和简洁的差异概述:

attr_accessor是在您的类中创build读写访问器的简单方法。 在数据库中没有列的情况下使用,但仍希望在表单中显示一个字段。 这个字段是Rails模型中的“virtual attribute”

虚拟属性 – 与数据库中的列不相对应的属性。

attr_accessible用于标识控制器方法可访问的属性,使属性可用于批量分配。它只会允许访问您指定的属性,否则就会拒绝其他属性。