我的用户模型上有一个受保护的字段,因为它确定了清除级别。因此它应该保留,而不是可分配的。因此,即使属性在3.2中默认受到保护,这实际上也是我想要的行为。
但是,在一个控制器方法中,我想允许管理员分配此字段,例如用户创建或用户更新。
如何为特定控制器操作分配该属性?
例如,我有我的控制器:
# app/controllers/admin/users_controller.rb
def create
@user = User.new(params[:user])
# ...
end
现在我要做的就是从clearance
中排除params[:user]
,但它似乎会在达到该行之前被过滤掉并引发异常(我尝试将debugger
置于右侧在该行之前甚至将其评论出来,它仍然引发了异常)。
保护属性在何处被捕获,如果不是,则在调用User#new
时
答案 0 :(得分:4)
The Rails way这样做是为了在没有保护的情况下分配属性或使用管理员角色:
@user = User.new
@user.assign_attributes(params[:user], :without_protection => true)
@user.save
然而,我发现这有点单调乏味,所以我写了一个名为sudo_attributes的宝石,它给我(在我看来)一个更好的API:
@user = User.sudo_new(params[:user])
@user.save
它模仿所有Rails实例化,创建和更新方法(new,build,create,create!,update_attributes等)。
答案 1 :(得分: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
现在看一下提到的the Rails way Beerlington,我宁愿使用角色,让特定的动作访问清除属性:
# /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
但这可能会导致再次出现错误。