Rails — Отношение, переданное в #или должно быть структурно совместимым. Несовместимые значения: [:соединения]

#sql #ruby-on-rails #activerecord

Вопрос:

Я хотел бы объединить два запроса в своем приложении rails. Каждый из них не очень сложен, но я не могу их объединить.

 owner_packages = Package.where(owner: current_user)
admins_packages = current_user.managed_packages
@managable_packages = owner_packages.or(admins_packages)
 

пользователь.rb

 has_many :package_admins, dependent: :destroy
has_many :managed_packages, through: :package_admins, source: :package
 

пакет.rb

   has_many :package_admins, dependent: :destroy
  has_many :admins, through: :package_admins, source: :user
 

Я сталкиваюсь с этой ошибкой:

Отношение, переданное в #или, должно быть структурно совместимым. Несовместимые значения: [:соединения]

Ответ №1:

Я думаю, что вы ищете подвыборку:

 owner_packages = Package.where(owner: current_user)
admins_packages = current_user.managed_packages
@managable_packages = owner_packages.or(Package.where(id: admins_packages))
 

Этот код действительно следует перенести в модель вместо того, чтобы оставлять все провода болтающимися:

 class User < ApplicationRecord
  has_many :owned_packages, class_name: 'Package',
                            foreign_key: :owner_id # just guessing here
  has_many :package_admins, dependent: :destroy
  has_many :managed_packages, through: :package_admins, source: :package


  def managable_packages 
    owned_packages.or(Package.where(id: managed_packages))
  end
end
 

Альтернативным методом является использование объединения:

 class User < ApplicationRecord 
  # ...

  def managable_packages
    Package.from(
      owned_packages.arel.union(managed_packages.arel).as('packages')
    )
  end
end
 

Комментарии:

1. отлично, спасибо! это именно то, что мне было нужно!