[英]CanCanCan: How to handle an object that is nil in Ability model?
我有这个控制器:
class UsersController < ApplicationController
load_and_authorize_resource
def create
@user.save
respond_with @user
end
def update
@user.update user_params
respond_with @user
end
def destroy
@user.destroy
respond_with @user
end
private
def user_params
permitted_keys = [:name,
:email,
:password,
:password_confirmation,
:lock_version]
permitted_keys << :role if can? :edit_role, @user
params.require(:user).permit(permitted_keys)
end
end
在我的能力模型中:
can :edit_role, User do |user|
user.new_record?
end
问题是,在创建用户( #new
或#create
动作)时, @user
为nil
。 所以角色不能被设置,因为它不会被添加到permitted_keys
上#create
。
如何解决呢? 我可以将控制器更改为:
permitted_keys << :role if action_name == 'create'
但是我不喜欢这样,因为测试Ability
比这容易得多。
另一个解决方法是:
permitted_keys << :role if can? :edit_role, @user || User.new
但这感觉多余。
有人有更好的主意吗? 顺便说一句-我很惊讶将nil
作为对象传递给can?
是允许的,不会引发错误。 似乎它甚至没有传播到Ability
的实际配置,否则为user.new_record?
会引发NoMethod
错误或类似错误。
CanCan docs规定了使用块定义功能的方式与您的操作方式略有不同。 他们建议针对您描述的情况(当实例为nil时)使用防护而不是块:
# don't do this
can :edit_role, User do |user|
user.new_record? # this won't be called for User.accessible_by(current_ability, :edit_role)
end
# do this
can :edit_role, User if user.new_record?
我会尝试的。 有关其他信息,并查看我在哪里获得此示例, 请查看以下文档
似乎使用CanCanCan gem,在创建@user
变量之前调用了user_params
方法。 user_params
是因为需要user_params
来创建@user
变量,或者至少需要从表单中分配值。
如果CanCanCan在分配表单中的值之前会分配一个新的@user
变量(当然是User
类型),那么以下代码将在#create
上#create
:
private
def user_params
permitted_keys = [:name,
:email,
:password,
:password_confirmation]
permitted_keys << :role if can? :edit_role, @user
permitted_keys << :disabled if can? :disable_user, @user
params.require(:user).permit permitted_keys
end
但是由于它显然没有做到这一点,因此以下变通办法对我有效:
private
def user_params
permitted_keys = [:name,
:email,
:password,
:password_confirmation]
auth_object = @user || User.new
permitted_keys << :role if can? :edit_role, auth_object
permitted_keys << :disabled if can? :disable_user, auth_object
params.require(:user).permit permitted_keys
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.