使用OR(逻辑联合)查询时,Pundit策略范围的无效构造函数错误

时间:2018-12-21 19:58:08

标签: ruby-on-rails ruby scope authorization pundit

我看到这种错误:

Invalid #<GroupPolicy::Scope> constructor is called

但是很奇怪,因为删除or()方法似乎绕过了错误-但我需要此方法来查找属于特定用户的网上论坛,并找到特定人可以编辑的网上论坛,然后返回该设置到索引页面。在这种情况下,用户是PORO,其中填充了来自AREST服务的员工数据。我认为我使用的方法不正确,因为抛出的错误与Pundit有关。

申请政策:

class ApplicationPolicy
  attr_reader :context, :record

  def initialize(context, record)
    @context = context
    @record = record
  end

  delegate :user, to: :context
  delegate :cookies, to: :context

  ...

  class Scope
    attr_reader :context, :scope

    def initialize(context, scope)
      @context = context
      @scope = scope
    end

    delegate :user, to: :context
    delegate :cookies, to: :context

    def resolve
      scope.all
    end
  end
end

组策略:

class GroupPolicy < ApplicationPolicy
  ...

  class Scope < Scope
    def resolve
      if user.admin?
        super
      else
        scope.joins(:group_editors).where(group_editors: { editor_id: user.id })
        # the above line works, but it doesn't work when I try:
        # scope.joins(:group_editors).where(group_editors: { editor_id: user.id }).or(scope.where(owner_id: user.id))
        # both queries succeed individually if I print them each on a new line
      end
    end
  end
end

组模型:

class Group < ApplicationRecord
  has_many :roles
  has_many :group_editors
  has_many :contents
end

编辑器型号:

class GroupEditor < ApplicationRecord
  belongs_to :group
end

组控制器(索引):

def index
  @groups = policy_scope(Group)
  redirect_to group_path @groups.first if @groups.count == 1
end

专家用户(使用其他上下文,因为有时在进行身份验证时会读取cookie)

def pundit_user
  UserContext.new(current_user, cookies)
end

class UserContext
  attr_reader :user, :cookies

  def initialize(user, cookies)
    @user = user
    @cookies = cookies
  end
end

编辑#1

这似乎可行-但是为什么呢?

scope.joins(:group_editors).where('owner_id = ? OR group_editors.editor_id = ?', user.id, user.id)

编辑#2

真正的错误是

Relation passed to #or must be structurally compatible. Incompatible values: [:joins]

这是不幸的。 Pundit引发误导性错误。

2 个答案:

答案 0 :(得分:0)

我在这里看到的唯一潜在问题是您两次调用了作用域。值得一试...

scope.joins(:group_editors).where(group_editors: { editor_id: user.id }).or(scope.where(owner_id: user.id))

可以这样重写吗

scope.joins(:group_editors).where(group_editors: { editor_id: user.id }).or(Group.where(owner_id: user.id))

答案 1 :(得分:0)

此问题已在母版中修复,将在下一发行版中发布。