This article will discuss how to implement authorization in a Ruby on Rails application using CanCanCan. Here’s how to start:
1
2
3
4
rails new cancancan-tutorial
rails g scaffold Post title body:text
gem 'devise'
gem 'cancancan'
Devise is required because CanCanCan needs current_user method defined. Run bundle install
, then add a devise user with user_type column.
1
2
rails g devise:install
rails g devise User user_type:string
Add two users in seeds.rb
.
1
2
3
4
# db/seeds.rb
User.create(email: 'customer@mintbit.com', password: '123123', password_confirmation: '123123', user_type: 'customer')
User.create(email: 'admin@mintbit.com', password: '123123', password_confirmation: '123123', user_type: 'admin')
Now run rails db:seed
, then create an ability.
1
rails g cancan:ability
Before setting ability, define a method that returns either true or false if current user is an admin or not.
1
2
3
4
# app/models/user.rb
def admin?
user_type == 'admin'
end
Now define an ability.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.admin?
can :manage, Post
else
can :read, Post
end
end
end
In app/controllers/application_controller.rb
, handle the error.
1
2
3
4
5
6
7
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
rescue_from CanCan::AccessDenied do |exception|
redirect_to root_url, :alert => exception.message
end
end
Now in app/controllers/posts_controller.rb
, put these two lines at the top:
1
2
before_action :authenticate_user!
load_and_authorize_resource
Now the admin will be able to create a post but the customer will not. Happy authorizing!