Saturday, May 9, 2015

Role based registration with devise and cancan using Ruby on Rails


It’s very bad that to solve this problem I had to spend many days. I need to register my client site two types of users. We can use role types. we will use devise for registration and by using cancan we will authorize the content. You can check the demo source code.


gem "devise"

$ bundle install
$ rails generate devise:install
$ rails generate devise User
$ rails generate devise:views
$ rake db:migrate
Add this link to layout- application.html.erb
<div id="user_nav">
  <% if user_signed_in? %>
    Signed in as <%= current_user.email %>. Not you?
    <%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
  <% else %>
    <%= link_to "Sign up", new_user_registration_path %> or 
<%= link_to "sign in", new_user_session_path %>
  <% end %>
</div>
Add a new file name registrations_controller.rb and put it, otherwise You can not insert anything on the role attribute –
class RegistrationsController < Devise::RegistrationsController
private

  def sign_up_params
    params.require(:user).permit( :email, :password, :password_confirmation , :role)
  end

  def account_update_params
    params.require(:user).permit(:email, :password, :password_confirmation, :current_password , :role , :name)
  end
  
end
and then Add this bold line –
devise_for :users, :controllers => { registrations: ‘registrations’ }
Now we can register and login using devise. Now we will add role attribute to the user table.
$ rails generate migration add_role_to_users role:string
$ rake db:migrate
Add this code on the views/devise/registration/new.html.erb
<%= f.collection_select :role, User::ROLES, :to_s, :humanize %>
Also add this model user.rb file.
class User < ActiveRecord::Base

ROLES = %w[admin moderator author banned]

end
 Now we will install can can.
gem "cancan"
Run this command –
rails g cancan:ability
just add a new class in `app/models/ability.rb`
class Abilityinclude CanCan::Abilitydef initialize(user)

user ||= User.new

can :manage, :all if user.role == "admin"

end

end
Suppose we want moderator can only edit the post. we can write like this –
can :manage, Post if user.role == "moderator"
Now we will test the cancan. Before it let me create posts controller using scaffolding.
$ rails generate scaffold Post name:string title:string content:text
$ rake db:migrate
Suppose we don’t want to show edit option to the guest user. You can use it on post view files.
<% if can? :read, @post %>
<%= link_to "Edit", edit_post_path(@post) %>
<% end %>
Hope you understand my tutorial, if u face any problem don’t hasitate to comment here.

1 comment:

  1. Hii, how to create polymorphic devise model
    ex: two user models doctors and patients should register in seperate pages but both should be able to login using users/sign_in.

    Any help would be appreciated please notify me at srujanaratna@gmail.com

    ReplyDelete