2

我的用户模型上有一个受保护的字段,因为它决定了许可级别。所以它应该受到保护而不是大量分配。因此,即使属性在 3.2 中默认受到保护,这实际上也是我想要的行为。

但是,在一种控制器方法上,我希望允许经理分配此字段,例如在用户创建或用户更新时。

如何允许为特定控制器操作分配该属性?

例如,我有我的控制器:

# app/controllers/admin/users_controller.rb

def create
    @user = User.new(params[:user])
# ...
end

现在我要做的是 exclude clearancefrom params[:user],但它似乎在到达该行之前就被过滤掉并引发和异常(我尝试debugger在该行之前放置一个权利,甚至将其注释掉,它仍然引发了一个异常)。

受保护的属性在哪里被捕获,如果不是在调用时User#new

4

2 回答 2

4

Rails执行此操作的方法是分配没有保护的属性或使用管理员角色:

@user = User.new
@user.assign_attributes(params[:user], :without_protection => true)
@user.save

但是,我发现这有点乏味,所以我编写了一个名为sudo_attributes的 gem ,它提供了(在我看来)更好的 API:

@user = User.sudo_new(params[:user])
@user.save

它模仿了 Rails 的所有实例化、创建和更新方法(new、build、create、create!、update_attributes 等)。

于 2012-06-12T01:48:06.780 回答
0

过去,我倾向于为这种操作提供自己包含的方法,它只设置这个值:

# app/controllers/admin/users_controller.rb

def full_clearance
  User.find(params[:id]).update_attribute(:clearance, 'full')
end

def restricted_clearance
  User.find(params[:id]).update_attribute(:clearance, 'restricted')
end

现在看看Beerlington 提到的 Rails 方式,我宁愿使用角色,让特定的操作访问权限属性:

# /app/models/user.rb

attr_accessible :attributes_accessible_by_default, ..., :clearance, :as => :manager

# app/controllers/admin/users_controller.rb

def create
    @user = User.new(params[:user].merge(:as => :manager)
# ...
end

在这种情况下,甚至可以根据用户的角色属性授予访问权限:

# app/controllers/admin/users_controller.rb

def create
    @user = User.new(params[:user].merge(:as => current_user.role.to_sym)
# ...
end

但这可能会导致再次引发错误。

于 2012-06-12T19:41:23.493 回答