【问题标题】:Finding all records that has at least one association from associated models (tables)从关联模型(表)中查找至少具有一个关联的所有记录
【发布时间】:2020-09-07 09:11:27
【问题描述】:
假设我有这个:
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
如何进行高效查询,以获取至少具有一个 Flower 或 Fruit 实例或两者兼有的所有 Tree 实例?这个想法是没有得到根本没有任何Flower 和Fruit 的Tree。
【问题讨论】:
标签:
ruby-on-rails
model
rails-activerecord
【解决方案1】:
我会使用这样的查询:
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)
【解决方案2】:
获取至少有一个Flower 或Fruit 的所有Trees 的一种非常基本的方法是这样的
flowers = Flower.pluck(:tree_id)
fruits = Tree.pluck(:tree_id)
然后是你想要的Trees
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))