1
module Abilities
  class ProjectsAbility < Ability
    def abilities
      can :manage, Project, user_id: user.id
      
      if user.is?(:super_admin)
        can :read, Project
      end

      if user.is?(:district_admin)
        can [:read, :manage_details, :download], Project, user: { district: { id: user_district_ids } }
      end

      if user.is?(:school_admin)
        can [:read, :manage_details, :download], Project, user: { school_id: user_school_ids || user.district.school_ids }
      end

      if user.is?(:advisor)
        can [:read, :manage_details, :download], Project, user: { advisors: { id: user.id } }
      end

      # alias_action :manage_details, :download, to: :read
    end
  end
end 

As district_admin, school_admin and advisor has same type of abilities. It can be agreed upon that all the users that have read access, have access to manage_details and download functionality.

So I was thinking that maybe I could achieve something like

alias_action :manage_details, :download, to: :read

But upon doing this I receive

CanCan::Error You can't specify target (read) as alias because it is real action name

The reason I decided to go with the above approach because I don't want to place

authorize! :read, @project in the controller action

However if I do alias_action :read, :manage_details, :download, to: :view_manage_details

and give users access to view_manage_details it works fine. Is there something that can be done to achieve alias_action :manage_details, :download, to: :read or is it something that requires extra mile work?

  • You're basically teetering on the edge where you're really going start hating CanCanCan as your autorization scheme seems to have a non-trivial level of complexity and CanCanCan turns into a total shit show in those situations. I would deal with the pain now and switch to Pundit. – max Feb 02 '23 at 10:56

0 Answers0