политики эксперта с пространствами имен

У меня есть модель вопроса в моем приложении.

приложение/модели/question.rb

class Question < ActiveRecord::Base
  ...
end

Я использую гем "pundit" для авторизации. Есть два контроллера для внесения некоторых изменений в вопросы: один для зарегистрированного пользователя, один для администратора.

Я пытаюсь создать отдельные политики для контроллеров.

приложение/контроллеры/questions_controller.rb

class QuestionsController < ApplicationController
   ...
end

приложение/политики/question_policy.rb

class QuestionPolicy < ApplicationPolicy
  ...
end

приложение/контроллеры/admin/questions_controller.rb

class Admin::QuestionsController < Admin::ApplicationController
  ...
end

приложение/политики/admin/question_policy.rb

class Admin::QuestionPolicy < Admin::ApplicationPolicy
  ...
end

Когда я пытаюсь использовать метод авторизации в Admin::QuestionsController, он использует класс app/policies/question_policy.rb не из папки администратора.

В документации Gem сказано, что это должно работать так, как я описал выше (https://github.com/elabs/pundit#namespaced-policies).

Может ли кто-нибудь помочь мне с этим?


person jizak    schedule 16.07.2014    source источник


Ответы (3)


Я пытался получить отдельные политики для основного приложения и ActiveAdmin и в итоге получил рабочее решение, создав индивидуальную PunditAdapter для использования в config/initializers/active_admin.rb.

class NamespacedPunditAdapter < ActiveAdmin::PunditAdapter
  def get_policy(subject, user, resource)
    "ActiveAdmin::#{subject}Policy".constantize.new(user, resource)
  end

  def retrieve_policy(subject)
    case subject
    when nil then get_policy(subject, user, resource)
    when Class then get_policy(subject, user, subject.new)
    else
      if subject.class.to_s.split('::')[0] == 'ActiveAdmin'
        Pundit.policy!(user, subject)
      else
        get_policy(subject.class, user, subject)
      end
    end
  end

  def scope_collection(collection, _action = Auth::READ)
    return collection if collection.class != Class
    scope = "ActiveAdmin::#{collection}Policy::Scope".constantize
    scope.new(user, collection).resolve
  rescue Pundit::NotDefinedError => e
    if default_policy_class && default_policy_class.const_defined?(:Scope)
      default_policy_class::Scope.new(user, collection).resolve
    else
      raise e
    end
  end
end

Другой вариант — использовать ActiveSupport::Concern, как указано здесь

person llekn    schedule 13.04.2018

Я создал проблему в исходном коде github, и она была закрыта с таким объяснением:

Документы относятся к невыпущенной на данный момент основной ветке. Вы можете использовать его, обратившись к источнику github в вашем Gemfile.

# Gemfile
gem 'pundit', github: 'elabs/pundit'
A bundle install later your code should work.

You can switch back to a released version on Rubygems as soon as 0.3.0 is out. We're still     discussing a few namespacing issues, but it will come soon.
person jizak    schedule 16.07.2014

Если кто-то все еще ищет эту функциональность, мне она также понадобилась для разделения авторизации между ActiveAdmin и моим сайтом, обращенным к конечному пользователю. Я создал гем, совместимый с Pundit, для авторизации в пространстве имен на основе контроллера (ваши политики будут работать), и я планирую следите за всеми функциями, выпущенными для pundit. Он также включает адаптер ActiveAdmin.

person Cory ODaniel    schedule 24.07.2015