Authentication, Permissions and Roles in Rails with Devise, CanCan and Role Model

Home / Development / Authentication, Permissions and Roles in Rails with Devise, CanCan and Role Model

We recently needed to implement a fairly standard user authentication / permission system on a Rails 3 project, with the ability to define these permissions using roles so that it could easily be centralized and expanded on (ie with new roles and permissions down the line). While rolling your own custom code is always an option, there is already a robust collection of gems to do exactly this. This blog post quickly presents how to combine three of these to implement this system.


Devise is a modular user authentication system thcgem ‘cancan’

  • Generate the Ability class which will contain your user permissions:
  • Open up this file and add the user line so that you can tie your abilities to the currently logged-in user:

Your application controller will need to know what to do if a CanCan exception is thrown:

Now you can decide which actions require CanCan authorization:

Adding this manually to every action in every controller is obviously a dumb idea, so you can just use load_and_authorize_resource at the top of your controller to authorize all actions in a RESTful fashion.

At this point you’ll want to actually make this more granular and allow abilities to be based on roles, which brings us to Role Model.

Role Model

The CanCan documentation provides a very nice explanation of the basic concept of using a bitmask to represent many roles per user, and Role Model is a ready-to-go solution if this approach fits your needs.

  • Add the role_model gem to your gemfile and run bundle install.
  • Edit your user.rb to make it aware of Role Model. With the existing Devise stuff, it should look more or less similar to this:

We effectively defined 3 roles now, now we need to update our ability.rb model to tie our permissions to them.

This is a really simple demonstration of what can be done fairly quickly with this stack, and in our application it was extended to leverage user-level custom permissions for specific assets and very fine-tuned abilities with conditional displays of specific view segments.