在Rails中,attr_accessor和attr_accessible有什么不同?据我所知,使用attr_accessor为该变量创建getter和setter方法,这样我们就可以访问像Object.variable或Object.variable = some_value这样的变量。
我读到attr_accessible让外部世界可以访问这个特定的变量。有人能告诉我有什么区别吗?
发布于 2010-06-29 06:04:09
attr_accessor是一个用来做getter和setter的方法。attr_accessible是一种Rails方法,它允许您将值传递给批量赋值:new(attrs)或update_attributes(attrs)。
这是一个大规模的任务:
Order.new({ :type => 'Corn', :quantity => 6 })您可以想象一下,订单也可能有一个折扣代码,比如:price_off。如果不将:price_off标记为attr_accessible,就会阻止恶意代码这样做:
Order.new({ :type => 'Corn', :quantity => 6, :price_off => 30 })即使您的表单没有用于:price_off的字段,如果它在您的模型中,那么它在默认情况下是可用的。这意味着一个精心制作的帖子仍然可以设置它。使用attr_accessible白名单列出那些可以批量分配的东西。
发布于 2012-10-18 00:21:13
在这个帖子和谷歌上的许多人都很好地解释说,attr_accessible指定了一个允许批量更新的属性白名单(同时对象模型的所有属性)这主要(也只是)保护您的应用程序免受“批量分配”盗版利用。
这在官方Rails文档中进行了解释:Mass Assignment
attr_accessor是一个用来(快速)在类中创建setter和getter方法的ruby代码。就这样。
现在,作为解释缺少的是,当您以某种方式在(Rails)模型和数据库表之间创建链接时,您永远不会,永远不需要在您的模型中使用attr_accessor来创建setter和getter,以便能够修改表的记录。
这是因为您的模型继承了ActiveRecord::Base类的所有方法,该类已经为您定义了基本的CRUD访问器(创建、读取、更新、删除)。这在官方文档Rails Model和Overwriting default accessor上都有解释(向下滚动到“覆盖默认访问器”一章)
例如:我们有一个名为"users“的数据库表,其中包含三列"firstname”、"lastname“和"role”:
SQL说明:
CREATE TABLE users (
firstname string,
lastname string
role string
);我假设您在配置/环境/Production.rb中设置了选项config.active_record.whitelist_attributes = true,以保护您的应用程序免受批量分配漏洞的攻击。这在这里解释:Mass Assignment
你的Rails模型将完美地与下面的模型一起工作:
class User < ActiveRecord::Base
end但是,您需要在您的控制器中分别更新user的每个属性,以便您的窗体视图能够正常工作:
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现在为了让你的生活更轻松,你不想为你的用户模型制作一个复杂的控制器。因此,您将在类模型中使用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您没有将“attr_accessible”属性添加到角色列表中,因为您不允许用户自己设置角色(如管理员)。您可以在另一个特殊的管理视图上执行此操作。
虽然您的用户视图没有显示“角色”字段,但盗版者可以很容易地发送在params散列中包含“角色”的HTTP POST请求。attr_accessible上缺失的“角色”属性是为了保护您的应用程序不受此影响。
您仍然可以像下面这样单独修改user.role属性,但不能将所有属性一起修改。
@user.role = DEFAULT_ROLE见鬼,你为什么要用 attr_accessor**?**
如果您的用户表单将一个在users表中不存在的字段显示为一列,就会出现这种情况。
例如,假设您的用户视图显示了一个“请告诉管理员我在这里”字段。您不希望将此信息存储在您的表中。您只想让Rails向您发送一封电子邮件,警告您一个“疯狂”的用户已经订阅了。
为了能够利用这些信息,您需要将其临时存储在某个地方。还有什么比在user.peekaboo属性中恢复它更简单呢?
因此,您可以将此字段添加到模型中:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
attr_accessor :peekaboo
end因此,您将能够合理地使用控制器中某处的user.peekaboo属性来发送电子邮件或做任何您想做的事情。
当您执行user.save时,ActiveRecord不会在您的表中保存"peekaboo“属性,因为她在模型中看不到任何与此名称匹配的列。
发布于 2010-06-29 06:07:10
attr_accessor是一个Ruby方法,它为同名的实例变量提供了setter和getter方法。所以它等同于
class MyModel
def my_variable
@my_variable
end
def my_variable=(value)
@my_variable = value
end
endattr_accessible是一种Rails方法,用于确定可以在批量赋值中设置哪些变量。
当你提交一个表单时,如果你有像MyModel.new params[:my_model]这样的东西,那么你想要有更多的控制,这样人们就不能提交你不想让他们提交的东西。
您可以使用attr_accessible :email,这样当有人更新他们的帐户时,他们可以更改他们的电子邮件地址。但是您不会使用attr_accessible :email, :salary,因为这样一个人就可以通过提交表单来设置他们的薪水。换句话说,他们可以通过砍掉加薪的方式获得加薪。
这类信息需要显式处理。仅仅将其从表单中删除是不够的。有人可以使用firebug进入,并将元素添加到表单中以提交一个薪水字段。他们可以使用内置的curl向控制器update方法提交新的薪水,他们可以创建一个脚本来提交包含该信息的帖子。
因此,attr_accessor是关于创建存储变量的方法,而attr_accessible是关于批量赋值的安全性。
https://stackoverflow.com/questions/3136420
复制相似问题