这是我想做的事情:
User
分配的admin
角色无法使用User
该角色更新god
角色。所以这是我想出的代码:
if user.has_role? 'admin'
can :manage, :all
cannot :update, User do |resource|
resource.has_role?('god')
end
end
然而,resource
似乎总是回归nil
。
有任何想法吗?
这是我想做的事情:
User
分配的admin
角色无法使用User
该角色更新god
角色。所以这是我想出的代码:
if user.has_role? 'admin'
can :manage, :all
cannot :update, User do |resource|
resource.has_role?('god')
end
end
然而,resource
似乎总是回归nil
。
有任何想法吗?
为了能够使用 and 的块语法#can
,#cannot
您必须首先在控制器中加载资源。正如医生所说:
仅当存在实际实例对象时才评估该块。在检查类的权限时(例如在 index 操作中),它不会被评估。这意味着任何不依赖于对象属性的条件都应该移到块之外。
要让这个实例对象出现,你需要让 cancan 加载它:
class UsersController < ApplicationController
load_and_authorize_resource
end
这将@user
在您的控制器和传递给#cannot
. 现在有一个问题。
CanCan 有 rails-4 的问题:它不处理 StrongParameters。这会导致自动资源加载崩溃#create
和#update
操作。这是一个正在运行的问题,Ryan 承诺为 cancan-2 提供解决方案(似乎已为 cancan-1 放弃)。
无论如何,您可以使用此 PR 中的代码使 cancan 兼容强参数。在这里,它被提取到一个猴子补丁中。我更喜欢使用猴子补丁而不是将 gem 指向特定的提交或分叉,这样我就不会丢失任何主 gem 更新。
再次阅读文档,我找到了另一种避免强参数问题的方法。如果在 #load_resource 之前使用 before_filter ,则可以重载加载器。
有几个含义:
#new
, #show
,#create
等之间产生差异(可以使用多个条件过滤器)#can
这破坏了 cancan 资源加载的简单性,并且唯一的目的是让 cancan 在您想使用带有and的块时知道资源是什么#cannot
。
我仍然宁愿使用猴子补丁,这样当上游修复问题时,你就不会在控制器中留下很多无用的代码。