Ruby on rails attr\u访问器和attr\u可访问之间的差异
在Rails中,Ruby on rails attr\u访问器和attr\u可访问之间的差异,ruby-on-rails,ruby,Ruby On Rails,Ruby,在Rails中,attr\u accessor和attr\u accessible之间有什么区别?据我所知,使用attr\u accessor可以为该变量创建getter和setter方法,这样我们就可以访问变量,如Object.variable或Object.variable=some\u value 我读到attr\u accessible使外部世界可以访问特定变量。 有人能告诉我有什么区别吗?attr\u accessor是一种Ruby方法,它可以生成getter和setterattr\u
attr\u accessor
和attr\u accessible
之间有什么区别?据我所知,使用attr\u accessor
可以为该变量创建getter和setter方法,这样我们就可以访问变量,如Object.variable
或Object.variable=some\u value
我读到attr\u accessible
使外部世界可以访问特定变量。
有人能告诉我有什么区别吗?attr\u accessor是一种Ruby方法,它可以生成getter和setter
attr\u accessible
是一种Rails方法,允许您将值传递给批量分配:new(attrs)
或update\u attributes(attrs)
这是一个集体作业:
Order.new({:type=>Corn',:quantity=>6})
您可以想象订单可能也有折扣代码,比如:price\u off
。如果您不将:price_off
标记为attr_accessible
您可以阻止恶意代码这样做:
Order.new({:type=>Corn',:quantity=>6,:price\u off=>30})
即使您的表单没有用于
:price\u off
的字段,如果它在您的模型中,默认情况下也是可用的。这意味着一个精心制作的帖子仍然可以设置它。使用attr\u accessible
white列出了那些可以批量分配的内容。attr\u accessor
是一种Ruby方法,它为相同名称的实例变量提供setter和getter方法。所以它相当于
class MyModel
def my_variable
@my_variable
end
def my_variable=(value)
@my_variable = value
end
end
attr\u accessible
是一种Rails方法,用于确定在批量分配中可以设置哪些变量
当你提交一个表单时,你有一些类似于MyModel.new参数[:my_model]
的东西,然后你想有更多的控制权,这样人们就不能提交你不希望他们提交的东西
您可以执行attr\u accessible:email
,这样当某人更新其帐户时,他们可以更改其电子邮件地址。但是你不会做attr\u accessible:email,:salary
,因为这样一个人就可以通过表单提交来设置他们的工资。换言之,他们可以通过黑客手段获得加薪
这类信息需要明确处理。仅仅从表单中删除它是不够的。有人可以使用firebug将元素添加到表单中,以提交薪资字段。他们可以使用内置的curl向controller update方法提交一份新的薪水,他们可以创建一个脚本来提交包含该信息的帖子
因此,
attr\u accessor
是关于创建存储变量的方法,而attr\u accessible
是关于批量赋值的安全性。attr\u accessor
是ruby代码,在数据库中没有列,但仍希望在表单中显示字段时使用。允许此操作的唯一方法是attr\u accessor:fieldname
,如果需要,您可以在视图或模型中使用此字段,但主要是在视图中
让我们考虑下面的例子
class Address
attr_reader :street
attr_writer :street
def initialize
@street = ""
end
end
这里我们使用了attr\u reader
(可读属性)和attr\u writer
(可写属性)进行访问。但是我们可以使用attr\u accessor
实现相同的功能。简而言之,attr\u访问器提供对getter和setter方法的访问。
所以修改后的代码如下所示
class Address
attr_accessor :street
def initialize
@street = ""
end
end
attr\u accessible
允许您列出要允许批量分配的所有列。与此相反的是attr_protected
,这意味着我不希望任何人被允许对该字段进行批量分配。更有可能的是,它将是数据库中的一个字段,您不希望任何人胡闹。类似于状态字段等。此线程和google上的许多人都很好地解释说,attr\u accessible
指定了一个允许批量更新的属性白名单(对象模型的所有属性同时一起更新)
这主要(也是唯一)是为了保护您的应用程序免受“大规模分配”盗版攻击
官方Rails文档对此进行了解释:
attr\u accessor
是一个ruby代码,用于(快速)在类中创建setter和getter方法。就这些
现在,缺少的解释是,当您以某种方式在(Rails)模型和数据库表之间创建链接时,您永远、永远、永远不需要在模型中创建setter和getter来修改表的记录
这是因为您的模型继承了ActiveRecord::Base
类的所有方法,该类已经为您定义了基本CRUD访问器(创建、读取、更新、删除)。
这里和这里的官方文档对此进行了解释(向下滚动到“覆盖默认访问者”一章)
例如:我们有一个名为“users”的数据库表,其中包含三列“firstname”、“lastname”和“role”:
SQL说明:
CREATE TABLE users (
firstname string,
lastname string
role string
);
我假设您在config/environment/production.rb中设置选项config.active\u record.whitelist\u attributes=true
,以保护应用程序免受大规模分配攻击。这里解释如下:
您的Rails模型将与以下模型完美配合:
class User < ActiveRecord::Base
end
现在,为了简化您的生活,您不想为您的用户模型制作复杂的控制器。
因此,您将在类模型中使用attr\u accessible
特殊方法:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
end
您没有将“角色”属性添加到attr\u accessible
列表中,因为您不允许用户自己设置角色(如管理员)。您可以在另一个特殊的管理视图中自己执行此操作
虽然您的用户视图没有显示“角色”字段,但盗版者可以很容易地发送一个HTTP POST请求,该请求在参数散列中包含“角色”。
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
@user.role = DEFAULT_ROLE
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
attr_accessor :peekaboo
end