Недопустимая ошибка конструктора для областей политики Pundit при использовании запросов OR (логическое объединение) - PullRequest
0 голосов
/ 21 декабря 2018

Я вижу такую ​​ошибку:

Invalid #<GroupPolicy::Scope> constructor is called

, но это очень странно, потому что удаление метода или () , кажется, обходит ошибку - но мне нужен этот метод, чтобынайти группы, которые принадлежат конкретному пользователю, и найти группы, которые конкретный человек может редактировать, и вернуть этот набор на страницу индекса.Пользователь в этом случае - это 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

Пользователь Pundit (использует дополнительный контекст, поскольку мы читаем файлы 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

Edit # 1

Это похоже на работу - но почему?

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

Edit # 2

Настоящая ошибка

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

, что вызывает сожаление.Pundit выдает ошибочную ошибку.

Ответы [ 2 ]

0 голосов
/ 22 декабря 2018

Эта проблема была исправлена ​​в master и станет частью следующего выпуска.

0 голосов
/ 22 декабря 2018

Единственная потенциальная проблема, которую я вижу здесь, это то, что вы дважды вызываете область.Стоит попробовать ...

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