Skip to content
Advertisement

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

I’d like to merge two queries in my rails app. Each one is not very complex but I can’t merge them.

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

user.rb

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

package.rb

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

I’m running into this error:

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

Advertisement

Answer

I think what you’re looking for is a subselect:

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

This code should really be moved into the model instead of leaving all the wires hanging out:

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

An alternative method is using a union:

class User < ApplicationRecord 
  # ...

  def managable_packages
    Package.from(
      owned_packages.arel.union(managed_packages.arel).as('packages')
    )
  end
end
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement