In a Rails 3.2 app I’m using Devise + CanCan. The app previously restricted access to only logged in users. I’m in the process of adding a Guest user/ability that will be able to read certain sections of the site.
I’m having trouble understanding the “correct” way to set this up, specifically what combination of before_filter :authenticate! and load_and_authorize_resource is needed in controllers.
While working on this I’ve stripped the ability class to a minimum.
#Ability.rb
class Ability
include CanCan::Ability
def initialize(user_or_admin)
user_or_admin ||= User.new
can :manage, :all
end
end
In a model-less/ static page Home controller
#home_controller.rb
class HomeController < ApplicationController
load_and_authorize_resource
def index
...some stuff
end
end
and
#application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :authenticate!
...more stuff
end
With this set up, un-logged-in users are redirected to Devise sign in page.
If I remove before_filter :authenticate! from the application controller I get an error uninitialized constant Home from activesupport-3.2.11/lib/active_support/inflector/methods.rb
If I remove load_and_authorize_resource from the home controller, this error goes away.
This is ok with my simplified testing Ability class, but as I start adding roles and abilities back in I will need to have CanCan handling the Home controller, i.e., will need load_and_authorize_resource to be called.
Can anyone help me understand why this error occurs when before_filter :authenticate! is removed, and point me towards any info that explain the “correct” way to set up Devise+Cancan for guest users. The info I’ve found thus far only explains how to set up the Ability class, not how to configure Devise.
The problem is that there is no resource to authorize. Therefore, you need only call
authorize_resourcenotload_and_authorize_resource. See authorizing controller actions in the cancan documentation for further information.Update: You must also specify the class as false:
authorize_resource class: false.Then your home controller will look like this:
This information is in the Non-RESTful controllers section. Sorry about that.