Search code examples
ruby-on-railscancanrolify

Cancan rolify : Define abilty on resource depending on role


I wonder if their are a way of using cancan to define abilities depending on role for a specific resource.

For now i have something like this, but the problem is that it goes through each role the user have each time like if he has 2 times the role1 even if it's on different Stuff instances.

def initialize(user)
    @user = user || User.new
    @user.roles.map(&:name).each{|name| send(name)}
  end

 def role1
    can :manage, Stuff
 end

How can i optimize this ?

I've thought about something like:

def initialize(user)
    @user = user || User.new

     can :manage, Object do |object|
       roles = @user.roles.where(resource_id: object.id, resource_type: object.class)
       unless roles.empty?
         roles.map(&:name).each{|name| send(name)}
       end
     end
  end

But it still got the problem of getting the ":manage" action to any user that have any other ability on the ressource...

So are their any way to access to the resource instance in the initialize function of cancan ?


Solution

  • I've found something for avoiding the :manage using this issue https://github.com/ryanb/cancan/issues/133

    so i've added

      def current_ability
        @current_ability = Ability.new(current_user, @resource)
      end
    

    in the application_controller.rb in the controller just before the "authorize!" call i've defined an instance variable named @resource

    like so:

    def create
        project = Project.find(params[:project_id])
        @resource = project
        authorize! :create_stories, project
        ....
     end
    

    and updated the ability.rb

     def initialize(user, resource)
        @user = user || User.new
    
        roles = @user.roles.where(resource_id: resource.id, resource_type: resource.class)
        if roles.empty?
          false
        else
          roles.map(&:name).each{|name| send(name)}
        end
      end
    
      def role1
        can :go_and_make_coffee
      end
    

    so enjoy if it helps someone