在Rails中,attr_accessor
和attr_accessible
之间有什么区别?根据我的理解,使用attr_accessor
用于为该变量创建getter和setter方法,以便我们可以访问Object.variable
或Object.variable = some_value
等变量。
我读到attr_accessible
使得该特定变量可供外界使用。
有人可以告诉我这是什么区别
答案 0 :(得分:254)
attr_accessor
是一个生成getter和setter的Ruby方法。 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
的字段,如果它在您的模型中,则默认情况下可用。这意味着精心设计的POST仍然可以设置它。使用attr_accessible
白色列出可以批量分配的内容。
答案 1 :(得分:171)
此线程和Google上的很多人都非常清楚地说明attr_accessible
指定了允许批量更新的属性列表(对象模型的所有属性同时在一起< /强>)
这主要是(并且仅)保护您的应用程序免受“大规模分配”盗版攻击。
这在官方Rails文档中解释:Mass Assignment
attr_accessor
是一个ruby代码,用于(快速)在Class中创建setter和getter方法。就是这样。
现在,作为解释的缺失是,当您以某种方式创建(Rails)模型与数据库表之间的链接时,您永远不会在模型中需要attr_accessor
来创建setter和getters为了能够修改表格的记录。
这是因为您的模型继承了ActiveRecord::Base
类的所有方法,它已经为您定义了基本的CRUD访问器(创建,读取,更新,删除)。
这在官方文档Rails Model和此处Overwriting default accessor上进行了解释(向下滚动到“覆盖默认访问者”一章)
比如说:我们有一个名为“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
现在为了减轻您的生活,您不希望为您的用户模型制作复杂的控制器。
因此,您将在类模型中使用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
?
嗯,如果你的用户表单显示一个不在你的用户表中作为列的字段。
例如,假设您的用户视图显示“请告诉管理员 - 我在这里”字段。 您不希望将此信息存储在表中。你只是希望Rails向你发送一封电子邮件警告你一个“疯狂”;-)用户订阅了。
为了能够使用此信息,您需要暂时将其存储在某处。
还有什么比在user.peekaboo
属性中恢复更容易?
因此,您将此字段添加到模型中:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
attr_accessor :peekaboo
end
因此,您可以在控制器中的某个地方有条不紊地使用user.peekaboo
属性来发送电子邮件或做任何您想做的事情。
当您执行user.save
时,ActiveRecord不会在表格中保存“peekaboo”属性,因为她在模型中看不到任何与此名称匹配的列。
答案 2 :(得分:47)
attr_accessor
是一个Ruby方法,它为您提供相同名称的实例变量的setter和getter方法。所以它相当于
class MyModel
def my_variable
@my_variable
end
def my_variable=(value)
@my_variable = value
end
end
attr_accessible
是一个Rails方法,用于确定可以在批量赋值中设置哪些变量。
当您提交表单时,如果有MyModel.new params[:my_model]
之类的内容,那么您希望获得更多控制权,以便人们无法提交您不希望他们提供的内容。
您可以执行attr_accessible :email
,以便当有人更新其帐户时,他们可以更改自己的电子邮件地址。但你不会attr_accessible :email, :salary
因为那时一个人可以通过表格提交来设定他们的工资。换句话说,他们可以破解他们的加薪方式。
需要明确处理这类信息。只是从表单中删除它是不够的。有人可以使用firebug并将元素添加到表单中以提交薪水字段。他们可以使用内置的curl向控制器更新方法提交新工资,他们可以创建一个脚本来提交包含该信息的帖子。
所以attr_accessor
是关于创建存储变量的方法,attr_accessible
是关于大规模分配的安全性。
答案 3 :(得分:18)
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
实现相同的功能。简而言之, attr_accessor提供对getter和setter方法的访问。
所以修改后的代码如下
class Address
attr_accessor :street
def initialize
@street = ""
end
end
attr_accessible
允许您列出要允许批量分配的所有列。与此相反的是attr_protected
,这意味着这个字段我不希望任何人被允许进行质量分配。很可能它会成为你数据库中的一个字段,你不希望任何人在一起工作。像状态字段一样。
答案 4 :(得分:2)
attr_accessor
是getter
,setter
方法。
而attr_accessible
则表示特定属性是否可访问。而已。
我希望补充一点,我们应该使用Strong parameter而不是attr_accessible
来防止大规模投降。
干杯!
答案 5 :(得分:2)
快速&amp;简明差异概述:
attr_accessor
是一种创建读写访问器的简便方法 你的班。当您的数据库中没有列时使用它, 但仍想在表单中显示一个字段。这个字段是 在Rails模型中“virtual attribute”
。虚拟属性 - 与数据库中的列不对应的属性。
attr_accessible
用于标识可访问的属性 通过您的控制器方法使属性可用 mass-assignment ..它只允许访问你的属性 指定,否认其余部分。