Использование Pundit с пространством имен

В моем проекте у меня довольно распространенное пространство имен "admin".

namespace :admin do
    resources :users, except: :show
end

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

-policies
    -admin
        user_policy.rb
    application_policy.rb
    admin_policy.rb
    awesome_policy.rb

очень похож на контроллеры.

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

class Admin::UserPolicy < AdminPolicy
end

Итак, в чем проблема, что я должен сделать, чтобы Pundit видел эти политики внутри пространства имен?

Ответ 1

С новым объединенным commit вы можете сделать это.

Он будет работать автоматически.

UPDATE:

От версии 0.3 эффективно удаляется без замены функции. Однако функцию пространства имен можно получить в ветке пространства имен на github.

Вы можете увидеть обсуждение функции в проблеме в github.

Мое предложение для людей, которые хотят использовать пространства имен с pundit, пока не использует. Сделайте перед фильтром доступ к запрещенной области, такой как панель управления admin, и оставьте правила модели авторизации в файлах pundit. Таким образом, вы сможете использовать pundit без хаков и проблем.

Ответ 2

Короткий ответ: вы не можете заставить Pundit использовать политики, связанные с пространством имен контроллера.

Длинный ответ: Pundit смотрит на ресурс (модель), чтобы определить, какой класс политики использовать, поэтому в любое время, когда вы передаете экземпляр модели User в качестве ресурса, он будет искать UserPolicy, а не Admin::UserPolicy

Смотрите здесь, здесь и здесь.

Вы можете указать класс политики в своей модели User, но на самом деле это не решит проблему с контроллером имен, поскольку Pundit собирается вывести класс политики из модели независимо от того, где вы авторизуетесь.

Ответ 3

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

В вашем случае в AdminPolicy я добавил пользовательские имена действий, например

def new_user?
  some code
end

а затем в моем действии Admin:: UserController # new

def new
  authorize @user, :new_user?
end