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

我读到attr_accessible使得外部世界可以访问特定的变量。 有人能告诉我有什么区别吗


当前回答

两个字:

Attr_accessor是getter, setter方法。 而attr_accessible表示特定属性是否可访问。就是这样。


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

干杯!

其他回答

一个快速而简洁的差异概述:

attr_accessor is an easy way to create read and write accessors in your class. It is used when you do not have a column in your database, but still want to show a field in your forms. This field is a “virtual attribute” in a Rails model. virtual attribute – an attribute not corresponding to a column in the database. attr_accessible is used to identify attributes that are accessible by your controller methods makes a property available for mass-assignment.. It will only allow access to the attributes that you specify, denying the rest.

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 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是getter, setter方法。 而attr_accessible表示特定属性是否可访问。就是这样。


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

干杯!