我对此question有类似的情况,已经发布了。 Koraktor问过
我使用一个简单的模型进行用户授权,使用两个ActiveRecords用户和角色用户和角色彼此之间具有HABTM关系。 。 。 使用@ user.roles或@ user.role_ids手动分配角色,但不是User#new或User#update_attributes中的“魔术”。
奥列格建议
attr_accessible :role_ids
添加到用户模型中。这将允许质量分配操作员更新角色。但是,由于担心安全问题,他告诫不要使用这种方法。
我对奥列格的回应有一个跟进问题 -
在这种情况下,是否有推荐的方法在不使用批量分配的情况下更新角色?
另外,假设
是对role_ids进行大规模分配还是一个有效的问题吗?
答案 0 :(得分:2)
批量分配是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并使用update_parameters
进行质量分配,那么如果从网址传递model[user][field4]=some_value
,则存在更新field4的风险或通过任何其他方式。如果我们明确指定代码中的字段,我们就没有这种风险。但是,我们必须为每个字段设置值(无论我们在哪里更新或创建),这都不是很有效率。
因此,对于使用质量分配功能,我们有2个选项。首先是attr_protected
attr_protected :field4
这将保护field4免于从params [:model]中进行质量分配,即使它包含field4。为了保存field4,我们必须明确地调用field4的setter
代码(@model.field4 =
)。但是,attr_protected
的问题是Rails可能提供一些我们可能不知道的大规模分配的其他属性。例如,如果我们定义
has_many :model2s
在Model.rb中,Rails将自动提供方法model2_ids=
,这可以通过批量分配来访问。(如果我们在URL中给出model[model2_ids]=
,它将创建关联,而不是根本不打算)。因此,使用attr_protected
时可能会遗漏这样的属性。
因此,推荐的方法是使用attr_accessible
attr_accessible :field1, :field2, :field3
这将使这些字段打开以进行质量分配,并且模型中的所有其他属性不可用于质量分配。因此,建议的方法是使用我们在表单中提供的那些属性供用户编辑为attr_accessible
,并且所有其他参数都将受到保护。但是,在使用此功能时,您必须确保已将编辑所需的所有属性包含在attr_accessible
中。
在您的情况下,由于您希望用户编辑role_ids
并且您仅为管理员用户提供CRUD访问权限,因此我认为您可以使用attr_accessible :role_ids
。另一种方法是明确指定role_ids
.role_ids = params[:user][:role_ids]
。如果您有其他不希望用户编辑role_ids的表单,则应使用此方法。