0

I'm using Rails 5 + Pundit gem and trying to fetch some chats with policy scope and model scope. Model scope has a query inside it and the problem is that policy scope applies to this inner query. The question is how to isolate the query from outer scope? Here's some code:

# 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

So I decided to output the inner sql query, which should get user chats' ids from the scope. I updated the model scope:

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

and here are results: when I run ChatPolicy::Scope.new(User.first, Chat).resolve.with_user(358) I get:

SELECT "chats".* FROM "chats" INNER JOIN "chat_users" "chat_users_chats" ON "chat_users_chats"."chat_id" = "chats"."id" INNER JOIN "chat_users" ON "chats"."id" = "chat_users"."chat_id" WHERE (chat_users.user_id = 350) AND "chat_users"."user_id" = 358

When I run Chat.with_user(358) I get:

SELECT "chats".* FROM "chats" INNER JOIN "chat_users" ON "chats"."id" = "chat_users"."chat_id" WHERE "chat_users"."user_id" = 358

It generates the correct query if I run it without policy scope. Is there a workaround?

LW001
  • 2,452
  • 6
  • 27
  • 36
Anton Grigoryev
  • 1,199
  • 11
  • 20
  • 1
    Have you tried to use `unscope`? – potashin Nov 14 '17 at 18:21
  • Yes, `unscope` and `unscoped` are nott working. By the way have found another interesting thing that when I run from console directly, without model scope: `ChatPolicy::Scope.new(User.first, Chat).resolve.where(chats: {id: User.find(358).chats.ids } )` it works somehow. – Anton Grigoryev Nov 14 '17 at 18:42

1 Answers1

0

This is a Community Wiki answer replacing the answer having been edited into the original question as recommended by Meta.

This has been solved by the OP with a different unscoped model scope:

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
}
LW001
  • 2,452
  • 6
  • 27
  • 36