使用 OR(逻辑联合)查询时权威策略作用域的构造函数错误无效



我看到这种错误:

Invalid #<GroupPolicy::Scope> constructor is called

但这很奇怪,因为删除 or() 方法似乎绕过了错误 - 但我需要此方法来查找属于特定用户的组并查找特定人员可以编辑的组,并将该设置返回到索引页。在这种情况下,用户是填充了来自 AREST 服务的员工数据的 PORO。我不认为我错误地使用了该方法,因为抛出的错误与 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]

这是不幸的。权威人士抛出了一个误导性错误。

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

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))

此问题已在 master 中修复,并将成为下一个版本的一部分。

最新更新