Skip to content

How To: Manage Users with an Admin Role (CanCan method)

Ben Koshy edited this page Feb 25, 2018 · 7 revisions

Based on Devise 1.1.3, Cancan 0.4.1, and uses Mongoid.

routes.rb

    DeviseRolesUserManagement::Application.routes.draw do
      devise_for :users
      devise_scope :user do
        get '/login' => 'devise/sessions#new'
        get '/logout' => 'devise/sessions#destroy'
      end
      resources :users, :controller => "users"
      root :to => "dashboard#index"
    end

users_controller.rb

class UsersController < ApplicationController
  load_and_authorize_resource

  def index
    @users = User.where.not(:id => current_user.id)
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      flash[:notice] = "Successfully created User." 
      redirect_to root_path
    else
      render :action => 'new'
    end
  end

  def edit
    @user = User.find(params[:id])
  end

  def update
    @user = User.find(params[:id])
    params[:user].delete(:password) if params[:user][:password].blank?
    params[:user].delete(:password_confirmation) if params[:user][:password].blank? and params[:user][:password_confirmation].blank?
    
    if @user.update(user_params)
      flash[:notice] = "Successfully updated User."
      redirect_to root_path
    else
      render :action => 'edit'
    end
  end

  def destroy
    @user = User.find(params[:id])
    if @user.destroy
      flash[:notice] = "Successfully deleted User."
      redirect_to root_path
    end
  end 
  private

  def user_params
     params.require(:user).permit(:email, :password, :password_confirmation)
  end
end

The views provide the all the links for the Users with an admin role to add and manage Users. I just created a role field for user and use CanCan to take care of the authorizations.

ability.rb

    class Ability
      include CanCan::Ability

      def initialize(user)
        can :manage, :all if user.role == "admin"
      end
    end

And then I catch unauthorized requests and redirect to root_url with a flash message.

application_controller.rb

    class ApplicationController < ActionController::Base
      protect_from_forgery
      rescue_from CanCan::AccessDenied do |exception|
        flash[:error] = exception.message
        redirect_to root_url
      end
    end

Brandon Martin Github App

Clone this wiki locally