3

I have extended the user model to allow me to do .can? checks on the user.

class User < ApplicationRecord
  def ability
    @ability = Ability.new self
  end
  delegate :can?, :cannot?, :to => :ability
end

This allows me to do things like @some_user.can? :edit, Book and get a result. (The cancan view helper, but in the model.). This works great.

I'd like to be able to do a reverse of that though and get all users that can do an action.

Example: Give me all users that can :edit, Books. User.can? :edit, Book which returns an active record collection.

To get this to work I did this;

class User < ApplicationRecord
  def self.can? sym, obj, *args
    uids = []
    User.all.each do |user|
      uids << user.id if user.can? sym, obj, args
    end
    User.where id: uids
  end
end

While this works, it feels really icky as it's iterating through each user and I'm concerned about scale.. is there a faster way to do this??

Jason Ellis
  • 625
  • 2
  • 8
  • 19

1 Answers1

0

i suggest combine cancan with rolify gem, with rolify you could pre-setup roles for users then your problem will turn into a query users who have the edit Book role

member_user.add_role :read, Book
admin_user.add_role :edit, Book

# query
User.with_role(:edit, Book) # [admin_user]
User.without_role(:edit, Book) # [member_user]
Lam Phan
  • 3,405
  • 2
  • 9
  • 20