如何将范围内的查询与权威策略范围隔离开来?

时间:2017-11-14 18:15:45

标签: ruby-on-rails postgresql ruby-on-rails-5 pundit

我使用Rails 5 + Pundit gem并试图获取一些具有策略范围和模型范围的聊天。模型范围内部有一个查询,问题是策略范围适用于此内部查询。问题是如何将查询与外部范围隔离开来?这是一些代码:

# 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查询,这应该让用户聊天&#39;来自范围的ID。我更新了模型范围:

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)时,我得到:

  

SELECT&#34;聊天&#34;。* FROM&#34;聊天&#34; INNER JOIN&#34; chat_users&#34;   &#34; chat_users_chats&#34; ON&#34; chat_users_chats&#34;。&#34; chat_id&#34; =&#34;聊天&#34;。&#34; id&#34;   INNER JOIN&#34; chat_users&#34; ON&#34;聊天&#34;。&#34; id&#34; =&#34; chat_users&#34;。&#34; chat_id&#34;哪里   (chat_users.user_id = 350)AND&#34; chat_users&#34;。&#34; user_id&#34; = 358

当我运行Chat.with_user(358)时,我得到:

  

SELECT&#34;聊天&#34;。* FROM&#34;聊天&#34; INNER JOIN&#34; chat_users&#34; ON&#34;聊天&#34;。&#34; id&#34;   =&#34; chat_users&#34;。&#34; chat_id&#34;在哪里&#34; chat_users&#34;。&#34; user_id&#34; = 358

如果我在没有策略范围的情况下运行它,它会生成正确的查询。有解决方法吗?

1 个答案:

答案 0 :(得分:0)

  

这是一个社区Wiki答案,将已编辑的答案替换为原始问题as recommended by 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
}