Trusted answers to developer questions
Trusted Answers to Developer Questions

Related Tags


How to define abilities in CanCan

Educative Answers Team

CanCan is an authorization library for Ruby on Rails that defines the authorization of specific resources for multiple users. All these permissions are set in a single locality (the Ability class) and are not duplicated across controllers, views, or database queries.

Below is an example of the Ability class:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= # guest user (not logged in)
    if user.admin?
      can :manage, :all
      can :read, :all

The current user model is passed into the initialize method to ensure that the permissions can be modified based on user attributes. No assumption takes place in the handling of roles.

Can method

The permissions are set using the can method, which requires two arguments:

can action, object


  • action is the action you are setting the permissions for
  • object is the class of the object you are setting it on

The action can be commonly set to:

  • :manage to represent any action
  • :read to allow the user to read the following object
  • :create to enable the user to create the next object
  • :update to allow the user to update the resulting object
  • :destroy to allow the user to delete the following object

The object can be set to include any class:

  • all can be set to apply the action to any object

The object and action can be passed as an array as well. This sets permissions for all objects and all actions.

can [:create, :destroy] , [Article, Comment]

Here, the user will be able to create and destroy both Article and Comments.

Note: If you apply :manage to an object, it sets all permissions, not just :read, create, :update, and :destroy.

If you only want to allow given permissions to be set when :manage is called, you can create a custom action:

def initialize(user)
  user ||=

  alias_action :create, :read, :update, :destroy, :to => :custom
  can :custom, User
  can :invite, User

Now, the :invite permissions are not set by default.

It is possible to define multiple abilities for the same resource:

can :destroy, Project, :deprecated => true
can :destroy, Project, :published => true

Here, the user is able to destroy all projects that have been published or deprecated.

Cannot method

The cannot method takes the same arguments as can and defines the actions the user is unable to perform.

This can be used to edit permissions after a generic call:

can :manage, Project
cannot :destroy, Project

The order of these calls is important.

Hash of conditions

A hash can be used to further restrict the record. An example of what these permissions apply to are:

can :read, Project, :user_id =>

Here, the user is only allowed to read projects that are owned by the user.

Note: Ensure that the columns used here are same as the column names in the database.

Nested hashes can also be used on the given conditions, like:

can :update, Project, :category => { :visible => true }

Here, the Project can only be edited if the category it belongs to is visible.

Furthermore, a range can be passed to set permissions for multiple values:

can :update, Project, :version => 1..3

However, this will not apply to model objects. For those, you will need to apply:

can :update, Project, :group => { :id => user.groups_ids }


Copyright ©2022 Educative, Inc. All rights reserved

View all Courses

Keep Exploring