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

Apercu edited this page Apr 18, 2014 · 3 revisions
Clone this wiki locally

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 :user, :controller => "user"
  root :to => "dashboard#index"
end

user_controller.rb

class UserController < ApplicationController
  load_and_authorize_resource

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

  def new
    @user = User.new
  end

  def create
    @user = User.new(params[:user])
    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_attributes(params[:user])
      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 
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