我刚刚在几个不同的位置对attr_accessor
、attr_accessible
和强参数进行了一些阅读:
attr_accessor和attr_accessible
的区别attr_accessible如何在 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
参数和强参数有什么区别?它们只是同一件事的不同名称吗?我们为什么要从一个转移到另一个?
任何信息都值得赞赏。
Rails 4 中已被弃用,取而代之的是强参数。
两者都是解决质量分配问题的不同方法,但强参数更灵活。
例如,您有一个属性为 email:string
和 is_admin:boolean
的 User
模型。您希望允许用户通过表单修改其电子邮件,而不是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 方法,可用于声明与数据库无关的模型属性、类或 PORO(普通旧 ruby 对象)的属性。
强参数和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
数据库列,则批量分配仅允许用户升级到管理员。哎呀!
这就是强参数的用武之地。使用强参数,如果您尝试进行幼稚的update(params[:user])
,Rails 将引发ActiveModel::ForbiddenAttributesError
。相反,您需要使用强参数提供的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 的维护者,但我喜欢强参数,因为它很灵活。如果我在用户控制器中有多个操作需要不同的参数,我可以轻松地使用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、批量分配或安全性无关。它恰好有一个相似的名字。:)