These days, I find myself implementing RailsAdmin 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 is easy, too!
Here is a step by step guide on how to set up RailsAdmin with Clearance authentication:
Step 1: Set up Clearance
# Gemfile
gem "clearance"
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.
# 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:
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 for more detail on how thoughtbot tests Rails applications.
# 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
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:
# 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:
# Gemfile
gem "rails_admin"
bundle install
Tell RailsAdmin where we want it mounted (here, we’re choosing at “/admin”)
# 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):
# 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”:
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:
ActiveRecord::UnknownAttributeError in RailsAdmin::MainController#new unknown attribute: password_confirmation
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:
# 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 when deciding whether or not to show a sign out link, we need to provide a little workaround:
# 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: