"CanCan is an authorization library for Ruby on Rails which restricts what resources a given user is allowed to access. All permissions are defined in a single location (the Ability class) and not duplicated across controllers, views, and database queries."
Add this to your Gemfile and run the bundle install command
gem 'cancancan', '~> 1.10'User permissions are defined in an Ability class
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.admin?
can :manage, :all
else
can :read, :all
end
end
endThe can method requires two arguments. The first one is the action you're setting the permission for, the second one is the class of object you're setting it on.
can :update, ArticleYou can pass :manage to represent any action and :all to represent any object.
can :manage, Article
can :read, :all
can :manage, :allA hash of conditions can be passed to further restrict which records this permission applies to
can :read, Project, active: true, user_id: user.idIf your conditions are too complex to define in a hash you can use a block
can :update, Project do |project|
project.priority < 3
endThe authorize! method in the controller will raise an exception if the user is not able to perform the given action.
def show
@article = Article.find(params[:id])
authorize! :read, @article
endThe current user's permissions can then be checked using the can? and cannot? methods
<% if can? :update, @article %>
<%= link_to "Edit", edit_article_path(@article) %>
<% end %>
If the user authorization fails, a CanCan::AccessDenied exception will be raised. You can catch this and modify its behavior in the ApplicationController.
class ApplicationController < ActionController::Base
rescue_from CanCan::AccessDenied do |exception|
redirect_to root_url, :alert => exception.message
end
endIf you want to ensure authorization happens on every action in your application, add check_authorization to your ApplicationController.
class ApplicationController < ActionController::Base
check_authorization
endThis will raise an exception if authorization is not performed in an action