attr_accessible和强参数之间的区别

时间:2015-06-11 15:17:11

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

我刚刚在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和强参数之间有什么区别?它们只是同一个东西的不同名称吗?我们为什么要从一个移到另一个?

感谢任何信息。

2 个答案:

答案 0 :(得分:19)

在Rails 4中已经弃用了

attr_accessible,而选择了强参数。

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

例如,您有一个User模型,其中包含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对象)的属性。

答案 1 :(得分:7)

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

“质量分配”是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数据库列,那么批量分配只是让用户升级到管理员。糟糕!

这就是强参数的来源。如果您尝试执行天真ActiveModel::ForbiddenAttributesError,使用强参数时,Rails将引发update(params[:user])。相反,您需要使用强参数提供的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不再支持此功能):您可以使用模型本身中的permit宏来执行类似的操作,而不是使用attr_accessible方法,像这样:

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

因此对于简单的情况,它与强参数非常相似;你只需在不同的地方定义属性列表。

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

<强> attr_accessor

attr_accessor宏内置于Ruby中,与Rails,批量分配或安全性无关。它碰巧有一个类似的名字。 :)