Использование cancan для предотвращения доступа к контроллеру

У меня есть контроллер администратора, и я хочу, чтобы только пользователи, которые определены как admin, имели доступ к этому контроллеру.

мой класс способностей:

class Ability
  include CanCan::Ability

  def initialize(user)
    if user.admin?
      can :manage, :all
    else
      can :read, :all
    end
  end
end

мой контроллер администратора:

class AdminController < ApplicationController
  load_and_authorize_resource

  def index
  end

  def users_list
  end
end

когда я пытаюсь получить доступ к /admin/users_list (либо с пользователем администратора, либо без него), я получаю следующую ошибку: uninitialized constant Admin

Что я делаю неправильно? Это правильный способ ограничить доступ к контроллеру?

Ответ 1

Это связано с тем, что при использовании load_and_authorize_resource ваш контроллер должен быть подкреплен моделью с именем Admin (так как ваш контроллер называется AdminController). Таким образом, вам нужно либо создать эту модель, либо заменить load_and_authorize_resource на:

authorize_resource: class= > false

который вызывает проверку доступа к вашим действиям, а не к модели. Обратите внимание, что это, к сожалению, приводит к общим символам доступа, таким как : управлять и : читать, чтобы прекратить работу, требуя, чтобы вы перенаправляли действия контроллера непосредственно в способность .rb:

может [: index,: users_list],: admin

где первый аргумент представляет собой массив действий контроллера, к которому пользователь может получить доступ, а второй аргумент - краткое имя контроллера

Ответ 2

Вы можете ввести авторизацию в свой контроллер

authorize_resource :class => false

или

authorize_resource :class => :controller

Затем измените свое приложение/модели/файл Ability.rb

can :manage, :controller_name

См. this

Ответ 4

Это связано с тем, что когда вы создаете общий контроллер, поместите load_and_authorize_resource, тогда контроллер приложения или контроллер администратора не смогут найти фактический класс, из которого он пришел, как в этом примере. Это будет работать.

class Admin::HomeController < Admin::ApplicationController
    def home    
    end
  end

  class Admin::ApplicationController < ApplicationController
    load_and_authorize_resource :class => self.class
  end

Ответ 5

У меня была такая же проблема. Моим решением было определение способности неспособности. Определено, что может сделать только администратор, я определяю, что не может сделать пользователь admin. В вашем коде будет что-то вроде этого:

Контроллер администратора:

class AdminController < ApplicationController
 authorize_resource :class => AdminController

 def index
 end

 def users_list
 end
end

ability.rb:

class Ability
 include CanCan::Ability

 def initialize(user)
  if user.admin?
   can :manage, :all
  else
   can :read, :all
   cannot [:index, :users_list], AdminController
  end
 end
end