【问题标题】:Difference between attr_accessible and strong parametersattr_accessible 和 strong 参数的区别
【发布时间】:2015-08-27 09:19:08
【问题描述】:

我刚刚阅读了attr_accessorattr_accessible 和几个不同位置的强参数:

Difference between attr_accessor and attr_accessible
How is attr_accessible used in Rails 4? http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html

我正在查看批量作业:

http://code.tutsplus.com/tutorials/mass-assignment-rails-and-you--net-31695

我无法理解attr_accessible 和强参数之间的区别。我对自己对上述主题的理解不是 100% 有信心,所以我可能会遗漏一些简单的东西,但我知道他们做的工作类似。

但是,attr_accessible 和强参数有什么区别呢?它们只是同一事物的不同名称吗?为什么我们从一个转移到另一个?

感谢任何信息。

【问题讨论】:

    标签: ruby-on-rails-4 strong-parameters attr-accessible


    【解决方案1】:

    在 Rails 4 中不推荐使用 attr_accessible 以支持强参数。

    两者都是质量分配问题的不同方法,但强参数更灵活。

    例如,您有一个Usermodel,其属性为email:stringis_admin:boolean。您希望允许用户通过表单而不是 is_admin 字段来修改他们的电子邮件。

    在 Rails 3 中你应该这样做:

    attr_accesible :email
    

    使用这种方法,用户无法修改 is_admin,因为该属性受到保护。

    强参数的好处之一是您可以在控制器中执行以下操作:

    def user_params
      if current_user.admin?
        params.require(:user).permit(:email, :is_admin)
      else
        params.require(:user).permit(:email)
      end
    end
    

    这样一个管理员用户就可以修改is_admin,而普通用户不能。

    这只是一个示例,并不是向用户授予管理权限的最佳方式,但它非常具有说明性。

    强参数的主要优点是它们在控制器中定义并且可以在运行时动态分配。 attr_accessible 是一种将属性列入白名单的更加静态和单一的方式。

    另一方面 attr_accessor 是完全不同的东西,仍然可以在 Rails 4 中使用,例如,如果您需要模型中的一个属性,它不需要持久化或写入数据库,但您需要它表单。想一想:

    attr_accessor :has_accepted_legal_terms

    这是一个 Ruby 方法,可用于声明与数据库无关的模型属性、Class 或 PORO(普通旧 ruby​​ 对象)的属性。

    【讨论】:

      【解决方案2】:

      强参数和attr_accessible 是向 Rails“批量分配”功能添加安全保护的两种不同方式。强参数是当前版本的 Rails 规定的方式。

      “Mass assignment”是 Rails 中一种方便的简写,它允许您在单个语句中设置模型的许多属性。

      例如,假设您有一个@user,您想使用来自表单提交的数据进行更新。如果没有批量分配,您将不得不编写如下乏味的代码:

      @user.first_name = params[:user][:first_name]
      @user.last_name = params[:user][:last_name]
      @user.phone_number = params[:user][:phone_number]
      ...
      @user.save
      

      每个表单域都在不断。

      使用批量分配,所有代码都变成了一行:

      @user.update(params[:user])
      

      但是,这充满了安全漏洞。 由于params 包含浏览器提交的任何数据,因此恶意用户可能会在该提交中添加您未预料到的数据。例如,他们可以将is_admin=1 添加到参数中。如果您有一个is_admin 数据库列,那么批量分配只是让用户升级为管理员。哎呀!

      这就是强参数的用武之地。使用强参数,如果您尝试执行幼稚的update(params[:user]),Rails 将引发ActiveModel::ForbiddenAttributesError。相反,您需要使用 Strong Parameters 提供的 requirepermit 帮助器明确说明您期望从浏览器提交中获得哪些参数。像这样:

      def user_params
        # Note that :is_admin is not permitted!
        params.require(:user).permit(:first_name, :last_name, :phone_number)
      end
      
      ...
      @user.update(user_params)
      

      我不能代表 Rails 的维护者,但我喜欢 Strong Parameters,因为它很灵活。如果我在用户控制器中有多个需要不同参数的操作,我可以使用permit 轻松描述应该允许的参数。

      或者,如果我有不同的用户角色可以更新不同的属性,那么我可以轻松地为这些权限建模。正如@CV-Gate 提到的,您甚至可以在运行时更改这些权限,这是一个强大的功能。

      简而言之,强参数的灵活性是由于您可以在任何地方定义user_params 方法,并且您可以随意定义。您拥有 Ruby 和 OO 概念的全部力量,可以让它按照您想要的方式工作。

      attr_accessible 呢?

      无需过多介绍(因为 Rails 不再支持此功能):您可以在模型本身中使用 attr_accessible 宏来做类似的事情,而不是使用 permit 方法,如下所示:

      class User < ActiveRecord::Base
        attr_accessible :first_name, :last_name, :phone_number
        ...
      end
      

      所以对于简单的情况,它的工作原理与强参数非常相似;您只需在不同的地方定义属性列表。

      但是,由于attr_accessible 与模型类的定义强耦合,因此您失去了很多灵活性。如果您有两个不同的控制器操作需要为同一个User 模型进行质量分配怎么办?现在你被卡住了。

      attr_accessor

      attr_accessor 宏内置于 Ruby 中,与 Rails、批量赋值或安全性无关。它只是碰巧有一个相似的名字。 :)

      【讨论】:

        猜你喜欢
        • 2011-03-09
        • 1970-01-01
        • 2013-06-27
        • 2011-02-08
        • 2010-12-28
        • 2019-09-23
        • 1970-01-01
        • 2019-07-21
        相关资源
        最近更新 更多