Skip to content

How To: Add an Admin Role

Akira Wong edited this page Feb 12, 2020 · 37 revisions

Option 1: With an Admin model

First generate the model and migration for the Admin role:

$ rails generate devise Admin

Configure your Admin model

class Admin < ActiveRecord::Base
  devise :database_authenticatable, :trackable, :timeoutable, :lockable 
end

Adjust the generated migration:

Devise 2.2:

class DeviseCreateAdmins < ActiveRecord::Migration
  def self.up
    create_table(:admins) do |t|
      t.string :email,              :null => false, :default => ""
      t.string :encrypted_password, :null => false, :default => ""
      t.integer  :sign_in_count, :default => 0
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.string   :current_sign_in_ip
      t.string   :last_sign_in_ip
      t.integer  :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
      t.string   :unlock_token # Only if unlock strategy is :email or :both
      t.datetime :locked_at
      t.timestamps
    end
  end

  def self.down
    drop_table :admins
  end
end

Earlier Devise Versions:

class DeviseCreateAdmins < ActiveRecord::Migration
  def self.up
    create_table(:admins) do |t|
      t.database_authenticatable :null => false
      t.trackable
      t.lockable
      t.timestamps
    end
  end

  def self.down
    drop_table :admins
  end
end

Routes should be automatically updated to contain the following

devise_for :admins

Option 2: Adding an admin attribute

The easiest way of supporting an admin role is to simply add an attribute that can be used to identify administrators.

$ rails generate migration add_admin_to_users admin:boolean

Add default: false to the line that adds the admin column to the table.

Your migration will now look like this:

class AddAdminToUsers < ActiveRecord::Migration
  def change
    add_column :users, :admin, :boolean, default: false
  end
end

Next, execute the migration script:

$ rails db:migrate

Now you're able to identify administrators:

if current_user.admin?
  # do something
end

If the page could potentially not have a current_user set then:

if current_user.try(:admin?)
  # do something
end

With the above way if current_user were nil, then it would still work without raising an undefined method admin? for nil:NilClass exception.

The code below can be used to grant admin status to the current user.

current_user.update_attribute :admin, true

Option 3: Using Active Record enum

You can see complete solution here, enum documentation here and the migration.

    rails g migration AddRoleToUsers role:integer
class User < ApplicationRecord
  enum role: [:user, :vip, :admin]
  after_initialize :set_default_role, :if => :new_record?

  def set_default_role
    self.role ||= :user
  end

  # ...
end

Then you can call:

user.admin?
user.admin!
user.role
user.user?
user.vip?
Clone this wiki locally