首页 > 解决方案 > Rails 5 cancancan定义多个条件的能力和单个条件的检查能力不起作用

问题描述

鉴于以下情况

用户.rb

class User < ApplicationRecord
  has_many :enrolments, dependent: :destroy
  has_many :teams, through: :enrolments
end

团队.rb

class Team < ApplicationRecord
  has_and_belongs_to_many :coaches, class_name: "User", join_table: "teams_coaches"
end

能力.rb

if user.canrole == "coach"
  can :read, User, canrole: "player", teams: { coaches: { id: user.id } }
end

我通过用户表中的一列区分了用户的角​​色。我需要教练只看到他执教的球队的球员。当我在 index 方法上使用 access_by 方法时,给定的规则成功运行, User.accessible_by(current_ability) 它只给我教练可以访问的那些球员。

但以下无法正常工作。 can?(:index, User.new(canrole: 'player')) 我使用这段代码来为教练用户显示一个名为“玩家”的导航菜单项。

预期行为

应该返回 true,因为can?(:index, User.new(canrole: 'player'))教练可以接触到一些球员。

实际行为

正在can?(:index, User.new(canrole: 'player'))返回 false


这有点类似于 https://github.com/CanCanCommunity/cancancan/blob/develop/docs/Checking-Abilities.md#checking-with-class

我们用哈希定义能力规则,但我们在不提供条件的情况下检查规则,但我们仍然得到 true 作为回报,因为用户至少可以访问一个项目

can :read, Project, :priority => 3
can? :read, Project # returns true

所以即使我们定义了具有多个条件的能力规则并且我们只检查一个条件的规则,它也应该返回 true,因为在检查实例时规则的条件之一是 true。


总结是,规则是用包含多个条件的条件哈希定义的,但是当我检查时,我只检查一个属性以使用它来检查我是否应该在导航菜单中显示“玩家”。因此,如果一个规则是用多个条件定义的,我们似乎不能只检查一个条件。

标签: ruby-on-railscancancan

解决方案


该动作can? :index只能在类级别上执行,通常用作默认User.accessible_by(current_ability)检查动作:index

如果您想知道“我可以指导至少一名球员吗?” 你需要做

User.accessible_by(current_ability).any?

推荐阅读