Как изолировать запрос внутри области от области политики эксперта?

Я использую гем Rails 5 + Pundit и пытаюсь получить некоторые чаты с областью политики и областью модели. В области модели есть запрос, и проблема в том, что область политики применяется к этому внутреннему запросу. Вопрос в том, как изолировать запрос от внешней области? Вот код:

# model
scope :with_user, ->(user_id=nil) {
  user_id ? where(chats: { id: User.find(user_id).chats.ids }) : all
}

# policy
class Scope < Scope
  def resolve
    if user.admin?
      scope.all
    else
      scope.joins(:chat_users).where(chat_users: { user_id: user.id })
    end
  end
end

Поэтому я решил вывести внутренний sql-запрос, который должен получить идентификаторы пользовательских чатов из области видимости. Я обновил область действия модели:

scope :with_user, ->(user_id=nil) {
  puts User.find(user_id).chats.to_sql
  where(chats: { id: User.unscoped.find(user_id).chats.ids } )
}

и вот результаты: когда я запускаю ChatPolicy::Scope.new(User.first, Chat).resolve.with_user(358), я получаю:

ВЫБЕРИТЕ «чаты».* ИЗ «чатов» ВНУТРЕННЕЕ СОЕДИНЕНИЕ «chat_users» «chat_users_chats» НА «chat_users_chats». «chat_id» = «чаты». «id» ВНУТРЕННЕЕ СОЕДИНЕНИЕ «chat_users» НА «чаты». «id» = «chat_users» "."chat_id" ГДЕ (chat_users.user_id = 350) И "chat_users"."user_id" = 358

Когда я запускаю Chat.with_user(358), я получаю:

ВЫБЕРИТЕ «чаты».* ИЗ «чатов» ВНУТРЕННЕЕ СОЕДИНЕНИЕ «chat_users» НА «чаты». «id» = «chat_users». «chat_id» ГДЕ «chat_users». «user_id» = 358

Он генерирует правильный запрос, если я запускаю его без области действия политики. Есть ли обходной путь?


person Anton Grigoryev    schedule 14.11.2017    source источник
comment
Вы пытались использовать unscope?   -  person potashin    schedule 14.11.2017
comment
Да, unscope и unscoped не работают. Кстати, нашел еще одну интересную вещь, что когда я запускаю из консоли напрямую, без области видимости модели: ChatPolicy::Scope.new(User.first, Chat).resolve.where(chats: {id: User.find(358).chats.ids } ) это как-то работает.   -  person Anton Grigoryev    schedule 14.11.2017


Ответы (1)


Это ответ вики-сообщества, заменяющий ответ, отредактированный в исходный вопрос в соответствии с рекомендациями Meta.

Это было решено с помощью OP с другой областью действия модели:

scope :with_user, ->(user_id=nil) {
  user_id ? where(chats: { id: Chat.unscoped.joins(:chat_users).where(chat_users: { user_id: user_id }).ids } ) : all
}
person Community    schedule 14.11.2017