Once the number of abilities definitions start to grow in number, it becomes more and more difficult to handle the Ability file.
The first strategy to handle these issue is to move abilities into meaningful methods, as per this example:
class Ability include CanCan::Ability def initialize(user) anyone_abilities if user if user.admin? admin_abilities else authenticated_abilities end else guest_abilities end end private def anyone_abilities # define abilities for everyone, both logged users and visitors end def guest_abilities # define abilities for visitors only end def authenticated_abilities # define abilities for logged users only end def admin_abilities # define abilities for admins only end end
Once this class grow large enough, you can try breaking it into different classes to handle the different responsibilities like this:
# app/models/ability.rb class Ability include CanCan::Ability def initialize(user) self.merge Abilities::Everyone.new(user) if user if user.admin? self.merge Abilities::Admin.new(user) else self.merge Abilities::Authenticated.new(user) end else self.merge Abilities::Guest.new(user) end end end
and then define those classes as:
# app/models/abilities/guest.rb module Abilities class Guest include CanCan::Ability def initialize(user) # Abilities for anonymous visitors only end end end
and so on with
Abilities::Admin or any other else.