Adding Actions to Devise Controllers
It wasn’t the most fun I could imagine having during a “holiday season” but while holed up in Chicagoland over Christmas I spent a couple of days porting a few of my older Rails apps to use a more up to date stack: Rails 3, Devise, Inherited Resources, Formtastic, etc. The idea is that if the apps are on a stack I use every day, I’ll spend less of my time reloading old tools into my head when the inevitable tweaks are required. We’ll see how that goes.
Anyway…
Two of the apps I was working on include member profile pages. Having carefully chosen my devise model names to match the language of my app I wanted to use the same controller that’s used for registrations for other member actions. Initially I tried just extending the relevant controller and updating the route:
config/routes.rb
devise_for :members, :controllers => { :registrations => "members" }
app/controllers/members_controller.rb
class MembersController < Devise::RegistrationsController
def show
...
end
end
but I kept getting ActionController::UnknownAction exceptions when I tried to request a member profile page.
It turns out that Devise runs a before_filter called is_devise_resource? in its controllers and that wasn’t recognising any actions that aren’t included in the core devise controllers. It also runs authenticate_scope! for relevant actions.
With that discovered it was easy enough to update my controller to
class MembersController [:index, :show, :edit, :update]
skip_before_filter :authenticate_scope!, :only => [:edit, :update, :destroy]
def show
...
end
end
and everything fell into place.