如何使用单个SQL查询从activerecord有效地检索对象组?

Puc*_*kXY 3 postgresql activerecord ruby-on-rails

我有一张桌子products,上面有一product_type_code列。我想做的是根据此列检索不同数量的对象(例如:3种产品product_type_code = 'fridge',6种产品product_type_code = 'car',9种产品product_type_code = 'house'等)。

我知道我可以这样:

fridges = Product.where(product_type_code: 'fridge').limit(3)
houses = Product.where(product_type_code: 'house').limit(9)
[...]
Run Code Online (Sandbox Code Playgroud)

甚至创建这样的范围:

# app/models/product.rb

scope :by_product_type_code, -> (material) { where(product_type_code: product_type_code) }
Run Code Online (Sandbox Code Playgroud)

但是,这效率不高,因为如果我没记错的话,我将数据库访问了3次。我想做的是这样的:

scope :by_product_type_code, -> (hash) { some_method(hash) }
Run Code Online (Sandbox Code Playgroud)

哈希在哪里: { fridge: 3, car: 6, house: 9 }

并获得一个ActiveRecord_Relation,其中包含3台冰箱,6辆汽车和9座房屋。

我如何有效地做到这一点?

Seb*_*lma 5

您可以使用UNION ALL创建查询,该查询选择具有特定条件的记录product_type_code并将limit其用于find_by_sql

{ fridge: 3, car: 6, house: 9 }.map do |product_type_code, limit|
  "(SELECT *
   FROM products
   WHERE product_type_code = '#{product_type_code}'
   LIMIT #{limit})"
end.join(' UNION ALL ')
Run Code Online (Sandbox Code Playgroud)

您将有一个类似的查询:

(SELECT * FROM products WHERE product_type_code = 'fridge'LIMIT 3)
UNION ALL
(SELECT * FROM products WHERE product_type_code = 'car'LIMIT 6)
UNION ALL
(SELECT * FROM products WHERE product_type_code = 'house'LIMIT 9)
Run Code Online (Sandbox Code Playgroud)