CanCan关联能力

时间:2018-05-17 13:32:53

标签: ruby-on-rails many-to-many associations cancan cancancan

我的问题是在以下背景下定义cancancan能力。

我有一个共同模型,用户和公司实体之间存在多对多的关系

class User < ApplicationRecord
    has_many :company_users, dependent: :destroy
    has_many :companies, through: :company_users 
    enum role:[:user, :admin, :superadmin]
end

class Company < ApplicationRecord
    has_many :company_users, dependent: :destroy
    has_many :users, through: :company_users
end

class CompanyUser < ApplicationRecord
    belongs_to :company
    belongs_to :user
end

我现在想要定义cancan功能,以便授权当前用户管理属于他的所有用户。

我对其他多对多模式没有问题(例如:设备和公司之间的多对多)

can :manage, Device, :companies => {:users => {:id => user.id}}

工作正常!

can :manage, User, :companies => {:users => {:id => user.id}}

当然,让我看看当前用户,因为它位于同一个用户表中。

如何在属于同一公司的用户之间轻松管理这种保持多对多关系的能力?

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

您可以使用范围解决问题:https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities-with-Blocks#block-conditions-with-scopes

并定义:

can :manage, User, User.joins(companies: :users).where(companies: { users: { id: user.id } })

请查看完整的要点:https://gist.github.com/coorasse/f1174b618651fcee8c65525d38b36120

答案 1 :(得分:1)

根据@coorasse的建议,我最终通过使用2个范围来解决我的问题,如下所示 在user.rb中

scope :company_list, -> (user_id) {CompanyUser.where(:user_id => user_id).pluck(:company_id)}
scope :owned_users,  -> (user_id) {CompanyUser.where(:company_id => company_list(user_id)).pluck(:user_id).uniq}

并在ability.rb

can :manage, User, id: User.owned_users(user.id)

这很好。