---
title: AuthorizedController
teaser:
tags: web,rails,testing,clearance,high_voltage
author: Dan Croak
published_on: 2011-06-07
---

We use a few Rails engines such as [High
Voltage](http://github.com/thoughtbot/high_voltage) and
[Clearance](http://github.com/thoughtbot/clearance) which allow you to override
default behaviors of controllers by subclassing them like:

    class SessionsController < Clearance::SessionsController
      layout 'public-facing'
    end

Meanwhile, we often work on apps which require most of the controllers to be
authorized. If we wanted to have a home page that uses High Voltage, one way we
might do it is:

    class ApplicationController < ActionController::Base
      include Clearance::Authentication # or other authentication mechanism
      before_filter :authorize
    end

    class PagesController < HighVoltage::PagesController
      skip_before_filter :authorize
    end

    MyApp::Application.routes.draw do
      # all the authorized routes
      resources :pages
    end

It's annoying to have a new route plus a new controller and to define and
override a `before_filter`. Meanwhile, the authorization logic is "hidden" in
`ApplicationController`.

Another way is:

    class ApplicationController < ActionController::Base
      include Clearance::Authentication
    end

    class CommentsController < ApplicationController
      before_filter :authorize
    end

For each controller, you call the `before_filter`. It's declarative in the sense
that when you read the `CommentsController` class, you can see it's protected by
authorization. The downsides are:

* you have to remember to write it for each controller
* you have to write some custom authorization specs for the controller

Another way is:

    class ApplicationController < ActionController::Base
      include Clearance::Authentication
    end

    class AuthorizedController < ApplicationController
      before_filter :authorize
    end

Now, we subclass from `AuthorizedController` for only those controllers that need
the functionality.

    class CommentsController < AuthorizedController
      # ...
    end

Again, it's declarative, we can read the class and know it's authorized. Again,
it requires we remember, which means we might forget.

I'd argue that if we <abbr title="Test Driven Development">TDD</abbr> the
controller, we shouldn't forget.

The advantage of subclassing from the intermediate AuthorizedController over
the `before_filter :authorize in each controller` style means we can feel
confident with a spec like:

    describe CommentsController do
      it { should be_kind_of(AuthorizedController) }
    end

That assumes we have a spec somewhere like:

    class MocksController < AuthorizedController
      def show
      end
    end

    describe MocksController do
      before do
        MyApp::Application.routes.draw do
          resource :mock, :only => [:show]
          match 'sign_in' => 'sessions#new', :as => :sign_in
        end
      end

      after do
        Rails.application.reload_routes!
      end

      context "a visitor" do
        it "is denied access to blank slate" do
          get :show
          should redirect_to(sign_in_url)
        end
      end
    end

If this style gains a little support, we could put `AuthorizedController` and
this spec into Clearance itself so it wouldn't need to be hanging around in
each of our app's codebases.

I feel like it's the right amount of work, with the right amount of test
coverage, without extraneous subclassing and routes.

Which approach do you prefer? Something different?
