质量分配是 Rails 的一个特性,它使用更少的代码来更新这样的模型
Model.create(params[:model])
@model.update_parameters(params[:model])
代替
@model.field1 = params[:model][:field1]
@model.field2 = params[:model][:field2]
...
@model.save
但是有了这个特性,就有更新我们不打算的值的风险。例如,如果我们只希望用户更新 field1、field2 和 field3,而您将其用于批量分配,那么如果从 url 或任何其他方式update_parameters
传递,则存在更新 field4 的风险。model[user][field4]=some_value
如果我们在代码中明确分配字段,我们就没有这种风险。但是随后我们将不得不为每个字段(无论我们在哪里更新或创建)设置值,这不是很有效率。
因此,对于使用质量分配功能,我们有 2 个选项。首先是attr_protected
attr_protected :field4
这将保护 field4 免于从 params[:model] 进行批量分配,即使它包含 field4。为了保存 field4,我们必须在 code( @model.field4 =
) 中显式调用 field4 的 setter。但是,问题attr_protected
在于 Rails 可能提供一些我们可能不知道的批量分配的其他属性。例如,如果我们定义
has_many :model2s
在 Model.rb 中,Rails 会model2_ids=
自动提供一个方法,并且可以通过批量赋值来访问它。(如果我们model[model2_ids]=
在 url 中给出,它会创建关联,根本不是有意的)。因此,在使用attr_protected
.
所以,推荐的方法是使用attr_accessible
attr_accessible :field1, :field2, :field3
这将使这些字段打开以进行批量分配,并且模型中的所有其他属性不可用于批量分配。因此,推荐的方法是将我们提供的那些属性以表格形式供用户编辑,attr_accessible
并且所有其他参数都将受到保护。但是,在使用它时,您必须确保已将编辑所需的所有属性包含为attr_accessible
.
在您的情况下,由于您希望用户编辑role_ids
并且您仅为管理员用户提供对 CRUD 的访问权限,因此我认为您可以使用attr_accessible :role_ids
. 另一种方法是明确分配role_ids
like .role_ids = params[:user][:role_ids]
。如果您有另一个表单,您不希望用户编辑 role_ids,您应该使用它。