Я использую гем 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
Он генерирует правильный запрос, если я запускаю его без области действия политики. Есть ли обходной путь?
unscope
? - person potashin   schedule 14.11.2017unscope
иunscoped
не работают. Кстати, нашел еще одну интересную вещь, что когда я запускаю из консоли напрямую, без области видимости модели:ChatPolicy::Scope.new(User.first, Chat).resolve.where(chats: {id: User.find(358).chats.ids } )
это как-то работает. - person Anton Grigoryev   schedule 14.11.2017