在Rails中,attr_accessor和attr_accessible之间的区别是什么?根据我的理解,使用attr_accessor用于为该变量创建getter和setter方法,以便我们可以像Object一样访问该变量。变量或对象。变量= some_value。
我读到attr_accessible使得外部世界可以访问特定的变量。 有人能告诉我有什么区别吗
在Rails中,attr_accessor和attr_accessible之间的区别是什么?根据我的理解,使用attr_accessor用于为该变量创建getter和setter方法,以便我们可以像Object一样访问该变量。变量或对象。变量= some_value。
我读到attr_accessible使得外部世界可以访问特定的变量。 有人能告诉我有什么区别吗
当前回答
这个线程和谷歌上的许多人都解释得很好,attr_accessible指定了一个允许批量更新的属性白名单(对象模型的所有属性同时更新)。 这主要(也是唯一)是为了保护你的应用程序不被“大规模分配”盗版利用。
这在官方Rails文档:质量分配中有解释
attr_accessor是一个ruby代码,用于(快速)在类中创建setter和getter方法。这是所有。
现在,需要解释的是,当您以某种方式在(Rails)模型与数据库表之间创建链接时,您永远、永远、永远都不需要在模型中使用attr_accessor来创建setter和getter,以便能够修改表的记录。
这是因为您的模型继承了ActiveRecord::Base Class中的所有方法,该类已经为您定义了基本的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模型做一个复杂的控制器。 所以你将在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
您没有将“role”属性添加到attr_accessible列表中,因为您不允许用户自行设置他们的角色(如admin)。您可以在另一个特殊的管理视图中自己执行此操作。
虽然你的用户视图没有显示“角色”字段,但盗版者可以很容易地发送一个HTTP POST请求,在params散列中包含“角色”。attr_accessible上缺失的“role”属性是为了保护您的应用程序不受此影响。
您仍然可以修改您的用户。单独的角色属性,如下面所示,但不是与所有属性一起。
@user.role = DEFAULT_ROLE
为什么要使用attr_accessor呢?
这是在用户表单显示用户表中不存在的字段作为列的情况下。
例如,假设您的用户视图显示了一个“请告诉管理员我在这里”字段。 你不希望将这些信息存储在你的表中。您只希望Rails向您发送一封电子邮件,警告您有一个“疯狂的”;-)用户订阅了。
为了能够使用这些信息,您需要暂时将其存储在某个地方。 还有什么比在用户身上恢复它更容易的呢。躲猫猫属性?
所以你把这个字段添加到你的模型中:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
attr_accessor :peekaboo
end
这样你就能合理地利用用户。Peekaboo属性,用于发送电子邮件或做任何您想做的事情。
ActiveRecord将不会保存“peekaboo”属性在您的表中,当您做一个用户。保存,因为她在模型中没有看到任何与此名称匹配的列。
其他回答
这个线程和谷歌上的许多人都解释得很好,attr_accessible指定了一个允许批量更新的属性白名单(对象模型的所有属性同时更新)。 这主要(也是唯一)是为了保护你的应用程序不被“大规模分配”盗版利用。
这在官方Rails文档:质量分配中有解释
attr_accessor是一个ruby代码,用于(快速)在类中创建setter和getter方法。这是所有。
现在,需要解释的是,当您以某种方式在(Rails)模型与数据库表之间创建链接时,您永远、永远、永远都不需要在模型中使用attr_accessor来创建setter和getter,以便能够修改表的记录。
这是因为您的模型继承了ActiveRecord::Base Class中的所有方法,该类已经为您定义了基本的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模型做一个复杂的控制器。 所以你将在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
您没有将“role”属性添加到attr_accessible列表中,因为您不允许用户自行设置他们的角色(如admin)。您可以在另一个特殊的管理视图中自己执行此操作。
虽然你的用户视图没有显示“角色”字段,但盗版者可以很容易地发送一个HTTP POST请求,在params散列中包含“角色”。attr_accessible上缺失的“role”属性是为了保护您的应用程序不受此影响。
您仍然可以修改您的用户。单独的角色属性,如下面所示,但不是与所有属性一起。
@user.role = DEFAULT_ROLE
为什么要使用attr_accessor呢?
这是在用户表单显示用户表中不存在的字段作为列的情况下。
例如,假设您的用户视图显示了一个“请告诉管理员我在这里”字段。 你不希望将这些信息存储在你的表中。您只希望Rails向您发送一封电子邮件,警告您有一个“疯狂的”;-)用户订阅了。
为了能够使用这些信息,您需要暂时将其存储在某个地方。 还有什么比在用户身上恢复它更容易的呢。躲猫猫属性?
所以你把这个字段添加到你的模型中:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
attr_accessor :peekaboo
end
这样你就能合理地利用用户。Peekaboo属性,用于发送电子邮件或做任何您想做的事情。
ActiveRecord将不会保存“peekaboo”属性在您的表中,当您做一个用户。保存,因为她在模型中没有看到任何与此名称匹配的列。
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_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方法,用于创建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是getter, setter方法。 而attr_accessible表示特定属性是否可访问。就是这样。
我想补充的是,我们应该使用Strong参数而不是attr_accessible来防止大量分配。
干杯!