Setting Up Role-Based Access Control with CanCan in Rails
In this article, we will explore how to implement role-based access control (RBAC) in a Rails application using the CanCan authorization library. This setup is particularly useful for applications like social networks where users can manage projects and collaborate with others.
Prerequisites
Before we begin, ensure you have the following:
- A Rails application set up with Devise for user authentication.
- A
Rolemodel to manage user roles.
Step 1: Define Your Models
First, let's define the Role and User models. The Role model will have a simple string attribute to represent the role name.
# app/models/role.rb
class Role < ApplicationRecord
has_many :users
# Example: roles could be 'admin', 'moderator', 'member'
validates :name, presence: true, uniqueness: true
end
# app/models/user.rb
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
belongs_to :role
end
Step 2: Setting Up CanCan
Next, we need to configure CanCan to handle authorization based on user roles. Create an Ability class where we will define permissions.
# app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.role.name == 'admin'
can :manage, :all
elsif user.role.name == 'moderator'
can :manage, Project
can :read, User
else
can :read, Project
end
end
end
Step 3: Assigning Roles to Users
When creating users, you can assign them roles based on your application's logic. For instance, you might have a user creation form that allows you to select a role.
# Example of assigning a role during user creation
user = User.new(email: 'example@example.com', password: 'password')
user.role = Role.find_by(name: 'member')
user.save
Step 4: Using CanCan in Controllers
In your controllers, you can now use CanCan to restrict access based on the user's role. For example:
# app/controllers/projects_controller.rb
class ProjectsController < ApplicationController
load_and_authorize_resource
def index
@projects = Project.all
end
def show
@project = Project.find(params[:id])
end
def create
@project = Project.new(project_params)
if @project.save
redirect_to @project
else
render :new
end
end
end
Conclusion
By following these steps, you can effectively manage user roles and permissions in your Rails application using CanCan. This setup allows users to collaborate on projects while ensuring that access is appropriately controlled based on their roles.
For further reading, you can explore the CanCanCan documentation for more advanced configurations and features.