How to use CanCan to implement authorization helpers in Rails

CanCan is a simple authorization strategy for Rails that is decoupled from user roles. All the permissions are stored in one single location. It is a popular authorization library for Ruby on Rails that restricts user access to specific resources.

Defining abilities

Abilities are defined in the Ability class using can and cannot methods. Lets look at the following example:

class Ability
  include CanCan::Ability

  def initialize(user)
    // The visitor and user
   // A registered user or a new user
    user ||= User.new

    can :read, Post

    // if a user is logged in
    if user.present?
      if user.admin?
        // admins have the privilege to manage everything
        can :manage, Post
        can :manage, :all
      else
     // other users are given permission to read and edit their own posts.
        can :read, Post
        // They cannot read any hidden articles
        cannot :read, Post, hidden: true
      end
    else
      // user not signed in should view a sign_up page:
      can :read, :sign_up
    end
  end
end

Getting started with CanCan

Permissions are defined in the Ability class and can be used from controllers, views, helpers, or any other place in the code.

To add authorization support, we first add the CanCanCan gem to our Gemfile:

gem cancancan

Then, we define the ability class:

# app/models/ability.rb
class Ability
  include CanCan::Ability

  def initialize(user)
  end
end

Secondly, in order to check authorization using load_and_authorize_resource to load authorized models into the controller, write:

class PostsController < ApplicationController
  load_and_authorize_resource

  def show
    // the post is already loaded and authorized
  end
end

Use authorize! to authorize or raise an exception.

def show
  @post= Post.find(params[:post_id])
  authorize! :read, @post
end

Use can? to check if an object is authorized against a particular action anywhere in the controllers, views, or helpers.

<% if can? :update, @post%>
  <%= link_to "Edit", post_path(@post) %>
<% end %>

This assumes the signed user is provided by the current_user method. If a user is provided access to update, then that user is provided with a link to edit the post.

Testing

CanCan can handle the entire permission logic inside the Ability class, which results in the efficient unit testing of applications.

The can? method can be called directly on any Ability so it is easy to test permission logic. Any user can be assigned certain access and any user can be restricted from having certain access. Look at the code below to see how a user can view the post and a restricted user cannot.

test_ability = Ability.new(User.first)
test_ability.can?(:show, Post) #=> true
other_ability = Ability.new(RestrictedUser.first)
other_ability.cannot?(:show, Post) #=> true

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved