ruby-on-rails - CanCanCan:如何处理能力模型中为零的对象?
问题描述
我有这个控制器:
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
on #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 文档规定了使用块定义能力的方法与您所做的方式略有不同。对于您描述的情况(当实例为零时),他们建议使用守卫而不是块:
# 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?
我会试试这个。有关其他信息并查看我从何处获得此示例,请查看这些文档
推荐阅读
- javascript - 这里如何计算参考框?
- python - 如何从 for 循环生成元组?
- java - 在字符串输入有机会输入之前执行的代码
- google-colaboratory - Google Colabs 中的 TensorFlow 2 在模型测试中失败了预处理错误
- php - 当我进入 php artisan 项目时如何解决这个问题:安装
- javascript - 将 django 字典(或 json 文件)传递给 javascript 函数
- python - Python:在 Intellij 中导入 ADI
- pythonanywhere - 得到一个我真的不明白的 WSGI 错误
- kubernetes - 访问 kubernetes 仪表板时出现错误尝试访问服务:'dial tcp 10.44.0.2:8443: connect: connection denied'
- ruby - Ruby 3 RBS 类型检查