ny95
ny95

Reputation: 710

CanCan Access Block

I'm working on a Rails 4 app that uses CanCan to grant access to users and I'm working on a can block but it doesn't seem that well written, i guess its pseudo code, its how i would like the ability to work. Can it be changed to work better or more efficient? I'm also trying to avoid unnecessary quires that could make the request take longer to process.

can :manage, User do |u|
  u.id.eql?(user.id) || u.account.founders.includes(u) || u.account.collaborators.includes(u)
end

Upvotes: 0

Views: 183

Answers (1)

Ryan Bigg
Ryan Bigg

Reputation: 107728

You've almost got the right code here already. Here's how I'd do it:

can :manage, User do |u|
  u.id == user.id ||
  u.account.founders.exists?(u.id) ||
  u.account.collaborators.exists?(u.id)
end

Comparing using == is the standard in Ruby. eql? is rarely used.

The exists? method will perform a lightweight database query and returns true if the database does contain that ID within those records. How you were doing it before was wrong, because includes is an ActiveRecord method for eagerly loading associations. Even if you used the similarly named include? method, it still would've loaded all the founders and collaborators for the account, and then used Ruby to check to see if those collections contained that user.

Upvotes: 2

Related Questions