CanCanCommunity / cancancan

The authorization Gem for Ruby on Rails.
MIT License
5.58k stars 639 forks source link

cancan slowing down page loads #219

Closed jdkealy closed 9 years ago

jdkealy commented 9 years ago

Hi,

I was wondering if there are smarter ways to optimize cancan. I see for example that once the permission has been satisfied, cancan keeps querying for other permission definitions. For example:

  can :manage, :all if user.has_role?:admin 
  # this is true 
  can :manage, Event if user.has_role? :event_manager

I'm finding that even though my current user has role "admin", it is hitting both queries on every page load, really slowing down my page load time.

Any pointers in regards to cacheing / optimizing / best practices would be most appreciated. Thanks!

Senjai commented 9 years ago

@jdkealy An ability is initialized for the current request. To do this it instantiates your ability class. Everything in MyAbility#initialize will run to determine what a user can or cannot do.

Instead of defining:

  can :manage :all if user.has_role? :admin 
  #etc

try short circuiting it with

  if user.has_role? :admin
    can :manage, :all
  else
    # can manage other things possibly maybe

Or check out the defining abilities with blocks guide on the wiki to have it run at check time.

Senjai commented 9 years ago

You can also eagerload your roles with includes to prevent additional queries.