attr_accessor和attr_accessible之间的区别
在Rails中, attr_accessor
和attr_accessible
什么attr_accessible
? 根据我的理解,使用attr_accessor
可以为该variables创buildgetter和setter方法,以便我们可以访问像Object.variable
或Object.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_accessor
是getter
, setter
方法。 而attr_accessible
就是说特定的属性是可以访问的。 而已。
我想补充说,我们应该使用强参数,而不是attr_accessible
来防止质量分配。
干杯!
一个快速和简洁的差异概述:
attr_accessor
是在您的类中创build读写访问器的简单方法。 在数据库中没有列的情况下使用,但仍希望在表单中显示一个字段。 这个字段是Rails模型中的“virtual attribute”
。虚拟属性 – 与数据库中的列不相对应的属性。
attr_accessible
用于标识控制器方法可访问的属性,使属性可用于批量分配。它只会允许访问您指定的属性,否则就会拒绝其他属性。