从关联模型(表)中查找至少有一个关联的所有记录

Finding all records that has at least one association from associated models (tables)

假设我有这个:

class Tree < ActiveRecord::Base
  has_many :fruits
  has_many :flowers
end

class Fruit < ActiveRecord::Base
  belongs_to :tree
end

class Flower < ActiveRecord::Base
  belongs_to :tree
end

如何进行高效查询以获取所有 Tree 实例,这些实例至少有一个 FlowerFruit 实例,或两者都有?这个想法是没有得到根本没有 FlowerFruitTree

获取至少有一个 FlowerFruit 的所有 Tree 的一种非常基本的方法是这样的

flowers = Flower.pluck(:tree_id)
fruits  = Tree.pluck(:tree_id)

然后是你想要的Tree

Tree.where(id: [flowers, fruits].flatten)

这会导致对您的数据库进行 3 次查询,这可能是问题,也可能不是问题,具体取决于您的用例。


一种更高级的方法是这样做,它只会产生一个查询。请注意 select 而不是 pluck 的使用,这使得 Rails 最终只发出一个查询成为可能。

flowers = Flower.select(:tree_id)
fruits  = Fruit.select(:tree_id)

Tree.where(id: flowers).or(Tree.where(id: fruits))

我会使用这样的查询:

Tree.left_joins(:fruits, :flowers).where('fruits.id IS NOT NULL OR flowers.id IS NOT NULL').distinct

它将产生这个 SQL:

SELECT DISTINCT "trees".* FROM "trees" LEFT OUTER JOIN "fruits" ON "fruits"."tree_id" = "trees"."id" LEFT OUTER JOIN "flowers" ON "flowers"."tree_id" = "trees"."id" WHERE (fruits.id IS NOT NULL OR flowers.id IS NOT NULL)