karellm
karellm

Reputation: 1933

CanCan abilities via Database and load_resource

My permissions are defined in a database like described on CanCan wiki. I want to authorize the :index only for the id in my permissions table, but still display the index page if no resource has been authorized.

If I use load_and_authorize_resource, it loads the resources based on the permissions. If I don't have any, the index action isn't accessible. I get an access denied on the resource.

If I still want to allow access to the :index action with no resource authorized, I see two options:

Option 1 (hate it) : Load manually the resources for the index.

class FirmsController < ApplicationController
  load_and_authorize_resource :except => :index

  def index
    @firms = user.permissions.where{action: ["index", "manage", "read"], subject_class: "Firm"}
  end
end

Option 2 (meh) : Add an ability for the :index with a constraint of id: [] (nothing) and overwrite it with my database permissions afterward.

class Ability
  include CanCan::Ability

  def initialize(user)

    user ||= User.new # guest user (not logged in)

    can :create, Firm
    can :index, Firm, id: []

    user.permissions.each do |permission|
      if permission.subject_id.nil?
        can permission.action.to_sym, permission.subject_class.constantize
      else
        can permission.action.to_sym, permission.subject_class.constantize, :id => permission.subject_id
      end
    end

  end
end

Option 3?

Can you think of a cleaner solution?

Upvotes: 1

Views: 1314

Answers (1)

Mark Huk
Mark Huk

Reputation: 2380

As stated in docs you should use helper method:

  skip_authorize_resource :only => :index

Upvotes: 1

Related Questions