---
title: Using Clearance with RailsAdmin
teaser:
tags: web,rails,open source,clearance
author: Jessie Young
published_on: 2014-08-13
---

These days, I find myself implementing
[RailsAdmin](https://github.com/sferik/rails_admin) on almost every consulting
project that I'm on. While RailsAdmin is not a replacement for a custom or
complex admin interface, it's a great way to give non-technical
stakeholders access to the data being created and updated in a Rails app. And
it takes just a few minutes to set up!

Where there is an admin interface, there is also authentication. Most of the
documentation out there covers how to integrate RailsAdmin with Devise. But
setting up RailsAdmin with
[Clearance](https://github.com/thoughtbot/clearance) is easy, too!

Here is a step by step guide on how to set up RailsAdmin with Clearance
authentication:

## Step 1: Set up Clearance

```ruby
# Gemfile
gem "clearance"
```

```bash
bundle install
rails generate clearance:install
```

Running the Clearance generator creates a migration. Clearance's generated
migration will either create the `users` table or add only the columns necessary
for Clearance to an existing `users` table. Before we run the migration, let's
add a boolean column to indicate whether a user is an admin or not.

```ruby
# db/migrate/20140808213224_create_users.rb
class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users  do |t|
      t.timestamps null: false
      t.boolean :admin, null: false, default: false
      t.string :email, null: false
      t.string :encrypted_password, limit: 128, null: false
      t.string :confirmation_token, limit: 128
      t.string :remember_token, limit: 128, null: false
    end

    add_index :users, :email
    add_index :users, :remember_token
  end
end
```

Now we're ready to run the migration:

```bash
rake db:migrate
```

## Step 2: Write a test

We want to be sure that only admin users can see our admin dashboard, so we'll
start with some feature specs that test this behavior. See [this overview of
testing Rails
applications](https://thoughtbot.com/blog/how-we-test-rails-applications) for
more detail on how thoughtbot tests Rails applications.

```ruby
# spec/features/admin_dashboard_spec.rb
feature "Admin dashboard" do
  scenario "visitor is admin" do
    admin = create(:admin)

    visit rails_admin_path(as: admin)

    expect(page).to have_content("Site Administration")
  end

  scenario "visitor is not an admin user" do
    user = create(:user)

    visit rails_admin_path(as: user)

    expect(page).to have_content("You are not permitted to view this page")
  end
end
```

The tests above are using
[`Clearance::BackDoor`](https://github.com/thoughtbot/clearance#faster-tests)
to sign the user in directly. This is one of Clearance's super awesome tools
that speeds up tests and makes writing feature specs a breeze.

Before these tests will run properly, we need to set up `admin` and `user`
factories:

```ruby
# spec/factories.rb
factory :user do
  email { "test@example.com" }
  password { "password" }

  factory :admin do
    admin { true }
  end
end
```

When we run our feature spec, our app does not recognize `rails_admin_path`, so
it's time to set up RailsAdmin.

## Step 3. Set up RailsAdmin

Add the gem:

```ruby
# Gemfile
gem "rails_admin"
```

```bash
bundle install
```

Tell RailsAdmin where we want it mounted (here, we're choosing at "/admin")

```ruby
# config/routes.rb
Rails.application.routes.draw do
  mount RailsAdmin::Engine => "/admin", as: "rails_admin"
```

When we run the tests again, we find that one of our tests is passing. Woot!

Unfortunately, the one that is failing is the spec that makes sure only admin
users can view RailsAdmin. That is no bueno.

Time to configure RailsAdmin to redirect non-admin users (we're assuming here
that we have a `root` path defined in our `routes.rb` file):

```ruby
# config/initializers/rails_admin.rb
RailsAdmin.config do |config|
  config.authorize_with do
    unless current_user.admin?
      redirect_to(
        main_app.root_path,
        alert: "You are not permitted to view this page"
      )
    end
  end

  config.current_user_method { current_user }
end
```

Now our tests both pass! But don't celebrate too quickly. There is one final
step we need to take care of: If we create an admin user in console, start our
server, and log in as that admin user, we will see the following form at
"/admin/user/new":

![rails admin new user](https://images.thoughtbot.com/using-clearance-with-rails-admin/rails-admin-new-user.png)

RailsAdmin assumes that because we have a `password` field, we will also have a
`password_confirmation` field. If we try to fill these fields out and save a new
user, we will get an error like this:

<pre>
<samp>ActiveRecord::UnknownAttributeError in RailsAdmin::MainController#new
unknown attribute: password_confirmation</samp>
</pre>

Clearance doesn't have a `password_confirmation` field, so we are unable to
create or update users in RailsAdmin out of the box. We can use the RailsAdmin
DSL for configuring which fields to expose:

```ruby
# config/initializers/rails_admin.rb
RailsAdmin.config do |config|

  ...

  config.model "User" do
    edit do
      field :admin
      field :email
      field :password
    end
  end
end
```

If we restart our server and re-load the admin dashboard, we'll see that only
the `admin`, `email`, and `password` fields are exposed and we can create a new
user from within RailsAdmin.

We're done! Now we can wow our teammates with the awesome admin dashboard we put
together in just a few minutes.

## Bonus: Add a sign out link to RailsAdmin

While we will probably include a sign out link in our main app, we've found
that admin users frequently look for a sign out link from within RailsAdmin.
Since RailsAdmin [looks for
Devise](https://github.com/sferik/rails_admin/search?q=logout_path) when
deciding whether or not to show a sign out link, we need to provide a little
workaround:

```ruby
# lib/rails_admin_logout_link.rb
RailsAdmin::ApplicationHelper

  module RailsAdmin
    module ApplicationHelper
      def logout_path
        main_app.send(:sign_out_path) rescue false
      end
    end
  end

  class Devise
    def self.sign_out_via
      :delete
    end
  end
```

After restarting our server, we see a bright red "log out" link in the upper
right hand corner of RailsAdmin:

![rails admin log out](https://images.thoughtbot.com/using-clearance-with-rails-admin/log-out-link.png)
