我刚刚在attr_accessor
,attr_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
和强参数之间有什么区别?它们只是同一个东西的不同名称吗?我们为什么要从一个移到另一个?
感谢任何信息。
答案 0 :(得分:19)
attr_accessible,而选择了强参数。
两者都是质量分配问题的不同方法,但强参数更灵活。
例如,您有一个User
模型,其中包含email:string
和is_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])
。相反,您需要使用强参数提供的require
和permit
帮助器明确说明您希望从浏览器提交的参数。像这样:
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,批量分配或安全性无关。它碰巧有一个类似的名字。 :)