-
Notifications
You must be signed in to change notification settings - Fork 0
Admin Namespace
By default, CanCan works best when the administration functionality is in the same controller as the public site. This way each resource only has one controller and set of actions it needs to handle permissions on.
However some sites work better when the administration section has its own separate set of controllers inside an Admin
namespace such as Admin::ArticlesController
. This means there are two controllers handling the same resource. Each controller will likely need different permission logic. The problem is that the Ability
model knows nothing about the Admin
namespace.
If you go with an Admin
namespace I recommend creating a base controller which all admin controllers inherit from. This is often a good thing to do with any namespace because it can help refactor out common functionality that exists in the controllers in that namespace.
# in controllers/admin/base_controller.rb
module Admin
class BaseController < ApplicationController
# common behavior goes here ...
end
end
Then use this as the superclass for each of those controllers.
# in controllers/admin/articles_controller.rb
module Admin
class ArticlesController < BaseController
# ...
end
end
Now several possibilities open up, and the one to go with depends on how complex the authorization needs to be in this admin namespace. If all you need to do is verify current_user.admin?
then you may want to skip CanCan altogether and use a simple before filter.
# in controllers/admin/base_controller.rb
before_filter :verify_admin
private
def verify_admin
redirect_to root_url unless current_user.try(:admin?)
end
There's really no need to use CanCan here because all the behavior is the same. However if you have various levels of admins which needs to access different things then that's a reason to use CanCan. In that case I recommend creating a separate Ability
class.
# in models/admin_ability.rb
class AdminAbility
include CanCan::Ability
def initialize(user)
# define admin abilities here ....
end
end
Then use this AdminAbility
for admin controllers.
# in admin/base_controller.rb
def current_ability
@current_ability ||= AdminAbility.new(current_user)
end
Now all admin permission logic will be handled in its own AdminAbility
class and everything else will be in the normal Ability
class.