Rails -传递给#or的关系必须在结构上兼容.不兼容的值:[:joins]



我想在我的rails应用程序中合并两个查询。每个查询都不是很复杂,但我不能合并它们。

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

我正在运行这个错误:

传递给#or的关系必须在结构上兼容。不兼容的价值观:[:连接]

我想你要找的是子选择:

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

当您尝试组合相同类型的两个多活动记录时,会发生这种情况,但是其中一个记录具有参考值或包含值,或者在您的情况下是连接值,而另一个没有。因此,我们需要匹配它们之间的值,我找到了一种通用的方法来做到这一点,而无需事先知道实际值。

admins_packages = current_user.managed_packages
owner_packages = Package.where(owner: current_user)
.joins(admins_packages.joins_values)
.includes(admins_packages.includes_values)
.references(admins_packages.references_values)
manageable_packages = admins_packages.or(owner_packages)

最新更新