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 Abilityinclude CanCan::Abilitydef initialize(user)user ||= User.new # guest user (not logged in)if user.admin?can :manage, :allelsecan :read, :allendendend
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.
The permissions are set using the can method, which requires two arguments:
can
action,object
where:
action is the action you are setting the permissions forobject is the class of the object you are setting it onThe 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 objectThe object can be set to include any class:
all can be set to apply the action to any objectThe 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 ||= User.new
alias_action :create, :read, :update, :destroy, :to => :custom
can :custom, User
can :invite, User
end
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.
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.
A hash can be used to further restrict the record. An example of what these permissions apply to are:
can :read, Project, :user_id => 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 }
Free Resources