Zyph Martin Design Studios Search


Zyph Martin Design Studios Recent Entries

THINGS I'M THANKFUL FOR

Posted on November 22 2012


BEST THING I'VE SEEN IN A LONG TIME.

Posted on April 11 2012


TELLING IT LIKE IT IS.

Posted on January 26 2012


COMING SOON TO A BROWSER NEAR YOU!

Posted on December 01 2011


SAY GOODBYE TO FLASH...

Posted on June 09 2011


VIEW ARCHIVES -->


MANAGE USERS WITH DEVISE AND CANCAN



Devise-cancan-blog

So I have been using Devise for all my rails projects that need authentication. I really enjoy working with devise. It has so many awesome features but it is really extendable when needed. One thing that I have been seeing on the mailing list for devise over and over is how an admin role can manage users. I know there is some stuff on the devise wiki about this but I thought why not add some more info and put an example app up on github. There are a few ways that you can achieve this and this is just the way I do it. If there are errors let me know and I will fix them. This is provided with no tests and is only to serve as an example. The github app is at http://github.com/brandmart/devise-roles-user-management. This example app is based on devise 1.1.3, cancan 0.4.1, and uses mongoid. I will just post the main code snippets and if you have any questions or suggestions feel free to leave comments.

#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

There is a ton of great information on the devise wiki and the cancan wiki that can answer most of your questions.



Back To Blog - Posted on October 03 2010 by Brandon Martin




blog comments powered by Disqus