3

我有一个使用 Cancan 进行授权的 Rails 3 应用程序。我的应用程序中有以下逻辑:管理员有权管理所有其他用户,并已can :manage, User在功能文件中设置。公司所有者有权管理其公司下的所有用户,并已can :manage, User, company_id: user.company_id在权限文件中进行了设置。

在我的UserController#index中,如果用户有权管理所有其他用户,我需要调用一种方法,如果用户只能访问他公司的用户,我需要调用另一种方法。有没有办法用 CanCan 做到这一点?

4

4 回答 4

3

正如问题评论中所讨论的,这听起来像是角色能力的案例。

如果已经有一个角色系统,并且在方法之间选择的逻辑直接映射到这些角色,那么通过 CanCan 能力是不必要的复杂。CanCan 擅长检查特定模型对象、类和集合的能力,但不擅长回到最初授予这些能力背后的原始逻辑。

在这种特定情况下,需要有一种方法来引用 case "can manage all Users in Company X but NOT all Users"。可能可以使用一些 if-else 结构来完成,但我认为这不是您真正想要的。特别是如果你的能力逻辑随着时间的推移而改变,它可能不再有意义。一个例子是所有用户都属于同一公司的极端情况,是否希望"all Users"即使对于非管理员公司所有者也调用该方法?

因此,我的建议是直接检查角色,就像你在Abilities课堂上已经做的那样。但我感觉到你的痛苦。;)

于 2013-08-13T13:31:09.593 回答
0

在控制器操作中,您应该执行以下操作:

#load @user variable 
begin
  authorize! :manage, @user
  #code when access is granted
rescue CanCan::AccessDenied
  #code when access is denied
end
于 2013-08-13T13:43:58.650 回答
0

我正在使用带有设备的cancan,在我的项目中我使用的可能与您想要的相同

if user_signed_in?
  if current_user.has_role? :admin
    @users = User.all
  end
else
  @users = User.where(current.user.company_id == company_id)
end
于 2013-08-13T13:24:12.867 回答
0

我知道这是一个老问题,但我也遇到了这种情况。我还希望ability.rb在一个地方完成所有角色检查文件。

我最终做的远非理想,但如果有人想走那条路,就记下来。我在下面定义了一个这样的新能力ability.rb

can :manage, :all_users if user.admin?

请注意,这:all_users只是我选择的一个随机名称,而不是 cancan 中的某种魔术方法。

在定义了这个能力之后,我可以在控制器中这样做:

if can? :manage, :all_users
  call_method_which_can_access_all_users
else
  call_method_which_can_access_only_some_users
end

但是,如果 Cancan 给我们提供一些东西,比如can? :manage, User, :all根据User参数后是否有用于过滤用户的哈希值,那就太好了。

于 2017-03-16T03:51:24.207 回答