0

我与此question类似,但已发布。 Koraktor问HABTM质量分配的替代方案

我用一个简单的模型用户授权与两个ActiveRecords用户和角色用户和角色之间有一个HABTM关系。 。 。 使用@ user.roles或@ user.role_ids手动分配角色的作用,但不是用户#new或User#update_attributes内的“魔术”。

奥列格建议

attr_accessible :role_ids 

被添加到用户模型。这将允许批量分配操作员更新角色。但是,他警告不要使用这种方法,因为安全问题。

我有一个跟进问题奥列格的回应 -

在这种情况下,有没有不使用大规模分配需要更新角色推荐的方法是什么?

此外,假设

  1. 你验证用户身份,
  2. 只允许管理员CRUD用户通过把一个的before_filter在users_controller,

是role_ids的质量,分配仍然是一个有效的关注?

回答

2

质量分配是提供了一种使用更少的代码,以更新模型这样

Model.create(params[:model]) 
@model.update_parameters(params[:model]) 

,而不是

@model.field1 = params[:model][:field1] 
@model.field2 = params[:model][:field2] 
... 
@model.save 

但与此功能的Rails的功能,来更新值的风险,这我们不打算。例如,如果我们只需要用户更新field1,field2和field3,并且您使用update_parameters进行批量分配,则如果通过url或其他方式传递model[user][field4]=some_value,则存在更新field4的风险。如果我们明确地分配代码中的字段,我们没有这种风险。但是,我们必须为每个字段设置值(无论我们正在更新还是创建),这不是非常有效。

因此,对于使用质量分配功能,我们有2个选项。首先是attr_protected

attr_protected :field4 

这将保护字段4被免于质量分配从PARAMS [:模式],即使它包含字段4。为了保存field4,我们必须在 代码(@model.field4 =)中明确调用field4的setter。但是,attr_protected的问题在于,Rails可能会提供一些我们可能不知道的用于批量分配的其他属性。例如,如果我们定义

has_many :model2s 

在Model.rb,Rails会自动提供一个方法model2_ids=并且这可以通过质量分配访问。(如果我们在U​​RL中给出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 = params[:user][:role_ids]那样明确地指定role_ids。你应该使用这个,如果你有另一个你不想让用户编辑role_ids的表单。

+0

谢谢你这个非常完整的解释。还有一个问题 - 如果我明确指定role_ids,我仍然需要使用'attr_accessible role_ids',对吧? – Kevin 2011-03-20 23:15:55

+0

否..'attr_accessible'与显式赋值无关。即使您声明了'attr_accessible:field1'或'attr_proteected:role_ids',您也可以明确指定'@user.roles ='或'@user .role_ids ='。在你提到的问题中,他忘了将'role_ids'添加到'attr_accessible'列表中。但是,他仍然可以分配'@user.roles ='或'@user.role_ids ='。 'attr_accessible'和'attr_protected'只影响质量分配。 – rubyprince 2011-03-21 03:13:56