attr_accessor和attr_accessible的区别

在Rails中,attr_accessorattr_accessible之间的区别是什么?根据我的理解,使用attr_accessor用于为该变量创建getter和setter方法,以便我们可以像Object.variableObject.variable = some_value那样访问变量。

我读到attr_accessible使外部世界可以访问特定的变量。 谁能告诉我有什么不同

128312 次浏览

attr_accessor是一个Ruby方法,用于创建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字段,如果它在你的模型中,默认情况下它是可用的。这意味着一个精心制作的POST仍然可以设置它。使用attr_accessible列出那些可以被质量分配的东西。

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是关于大量赋值的安全性。

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,这意味着我不希望任何人被允许批量分配到这个字段。它很可能是数据库中的一个字段,您不希望任何人随意摆弄它。比如状态字段之类的。

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

这在官方Rails文档中有解释:大量的任务

attr_accessor是一个ruby代码,用于(快速)在一个类中创建setter和getter方法。这是所有。

现在,缺少的解释是,当你以某种方式创建(Rails)模型与数据库表之间的链接时,你永远、永远、永远都不需要在你的模型中attr_accessor来创建setter和getter,以便能够修改表的记录。

这是因为你的模型继承了ActiveRecord::Base类的所有方法,该类已经为你定义了基本的CRUD访问器(创建、读取、更新、删除)。 这在这里的官方文档Rails模型和这里重写默认访问器(向下滚动到“覆盖默认访问器”一章)

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

SQL指令:

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

我假设你在配置/环境/生产中设置了选项config.active_record.whitelist_attributes = true。rb保护您的应用程序免受大规模分配利用。这里解释:大量的任务

您的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
现在为了简化你的生活,你不想为你的User模型做一个复杂的控制器。 所以你将在你的类模型中使用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

你没有将“role”属性添加到attr_accessible列表中,因为你不让你的用户自己设置他们的角色(比如admin)。您可以在另一个特殊的管理视图中自己执行此操作。

虽然你的用户视图没有显示“角色”字段,但盗版者可以很容易地发送一个HTTP POST请求,在params散列中包含“角色”。attr_accessible中缺少的“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”属性,因为她在她的模型中没有看到任何与此名称匹配的列。

两个字:

attr_accessorgettersetter方法。 而attr_accessible表示该属性是否可访问。就是这样。< / p >


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

干杯!

快速&简要的差异概述:

attr_accessor是一种创建读写访问器的简单方法 你的类。当你的数据库中没有列时, 但仍然想在表单中显示字段。这个领域是 “virtual attribute”在Rails模型中

虚拟属性 -一个不对应于数据库中的列的属性。

attr_accessible用于标识可访问的属性 方法使属性可用 质量确定. .它将只允许访问您所选择的属性

.

.

.