You do not need to use load_and_authorize_resource in each controller. This is a handy macro that does two things. First, it assigns an instance variable to the record (s) accepted for the current controller and action. Then it resolves the resource. For some controller actions, the first step may be incorrect, so you want to upload your resource and then authorize it manually. An example from the Railscasts episode about CanCan is as follows:
def edit @article = Article.find(params[:id]) unauthorized! if cannot? :edit, @article end
You can also do this as in the CanCan Wiki example for authorizing controllers :
def show @project = Project.find(params[:project]) authorize! :show, @project end
Or you can just use authorize_resource and take care of loading it yourself. In the end, you have to make sure that CanCan is used for authorization in some way (controller macro or in every action). As for your abilities, I think you want something like this:
class Ability include CanCan::Ability def initialize(user) user ||= User.new # guest user (not logged in) #Admin if user.has_role? :admin can :manage, :all # Editor elsif user.has_role? :editor can :read, :all can :manage, :newsroom can :manage, Post #Member elsif user.has_role? :member can :read, :all can :create, Post can :status, Post can :update, Post do |post| post.try(:user) == user end #Guest else can :read, :all cannot [:index, :published, :unpublished], :newsroom end end end
And here is an example, for example, how you can authorize your edition:
class ToolsController < ApplicationController authorize_resource :class => false def show # automatically calls authorize!(:show, :tool) end end
The last personal note about CanCan is that I would not offer it for new projects, as it is not actively supported and that I found it a little contradictory in determining abilities. However, CanCan is one of the most well-documented gems I've worked with, especially the wiki contains many examples and explanations.