Search code examples
ruby-on-railsrubydevisecancan

How to restrict the access to models for different user roles in rails (cancan gem)?


I want 3 user levels as Admin ,Manager,Customer in my rails application. So i've created 3 devise models as admin,manager and customer. And in my application there are models and controllers for product,delivery,services. And I want to set access levels to each models.

So Admin have access to all models, controllers

Manager have access to Product, Delivery

Customer have access to Services

how can i write the ability model to match these requirements I've written it as follows.Don't know whether it's correct.

class Ability
  include CanCan::Ability
    def initialize(user)
        # Define abilities for the passed in user here. For example:
        #
          user ||= User.new # guest user (not logged in)
          if user.admin?
            can :manage, :all
          elsif user.manager?
            can :manage, product ,delivery
          elsif user.customer?
            can :manage, services
          end
    end

AND PLEASE HELP ME TO WRITE THE CODE FOR THE MODELS TO RESTRICT DIFFERENT USER ROLE ACCESS. PLEASE BE KIND ENOUGH TO HELP ME!


Solution

  • I think the easiest way to tackle this would be in your controller. Let us say you had a book model with controller, and only wanted to allow admins to access this part. It's probably best to create a method in your bookings controller, and call it using the before action method:

    class BookingsController < ApplicationController
      before_action :check_admin
    
      def check_admin
        return unless admin_signed_in?
        redirect_to root_path, error: 'You are not allowed to access this part of the site'
      end
    end
    

    This will perform the check_admin method every time anything happens in the bookings controller, and will redirect to your root path unless an admin is signed in. Devise also comes with user_signed_in? and manager_signed_in? helpers if you've created models with those names.

    You can tailor this more by deciding which controller actions will perform the action, for example

    before_action :check_admin, only: [:edit, :create, :delete, :update, :new]
    

    Would only perform the check before those controller actions, and allow anyone to access the index and show actions.