Reputation: 264
My question is about defining cancancan ability in this following context.
I have a common model with many to many relationship between User and Company entities
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
I want now to define cancan ability in order to authorized current user to manage all the users belonging to the same companies as him.
I have no problem with other many to many schemas (eg : many to many between Device and Company) like this
can :manage, Device, :companies => {:users => {:id => user.id}}
is working fine !
but
can :manage, User, :companies => {:users => {:id => user.id}}
let me see, of course, only the current user because it is on the same users table.
How can I manage easily this ability between users belonging to a same company preserving the many to many relationship ?
Thanks for your help
Upvotes: 2
Views: 2682
Reputation: 264
Upon the @coorasse recommandations, I finally solve my problem by using 2 scopes as following in 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}
and in the ability.rb
can :manage, User, id: User.owned_users(user.id)
This is working fine.
Upvotes: 2
Reputation: 5528
You can solve the issue using scopes: https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities-with-Blocks#block-conditions-with-scopes
and defining:
can :manage, User, User.joins(companies: :users).where(companies: { users: { id: user.id } })
please look at the full gist: https://gist.github.com/coorasse/f1174b618651fcee8c65525d38b36120
Upvotes: 5