[英]How can I order nested includes records with Rails 4
As the title states: how can I order nested includes
records with Rails 4? 如标题所述:如何使用Rails 4订购嵌套的
includes
记录?
Here is an overview of the models: 以下是模型的概述:
Product 产品
ProductSize 产品尺寸
Size 尺寸
A Product
has many Sizes
through ProductSize
. 通过
ProductSize
Product
具有多种Sizes
。 Sizes
are to be ordered through order
on the Size
model. Sizes
是通过订购order
在Size
模型。 I have a default_scope
of order('order DESC')
set on the Sizes
model 我在
Sizes
模型上设置了default_scope
of order('order DESC')
I want to be able to get a list of products
, and then loop through each product
and show a list of available sizes
, ordered by the size
order
. 我希望能够获得
products
列表,然后遍历每个product
并显示可用sizes
的列表,按size
order
。 I want this all without making inefficient queries (n+1 problem), so I am using includes
. 我希望所有这些都不会造成效率低下的查询(n + 1问题),因此我正在使用
includes
。
To do this, I run Product.includes(:product_sizes => [:size]).all
which generates: 为此,我运行
Product.includes(:product_sizes => [:size]).all
会生成:
SELECT "products".* FROM "products"
SELECT "product_sizes".* FROM "product_sizes"
WHERE "product_sizes"."product_id" IN (X, X, X, X)
SELECT "sizes".* FROM "sizes"
WHERE "sizes"."id" IN (X, X, X, X, X, X, X, X) ORDER BY `order` ASC
As you can see my my ordering will be off since it will use the order in which I got the records from the product_sizes
query. 如您所见,我的排序将关闭,因为它将使用从
product_sizes
查询中获取记录的顺序。 You can also notice that the query for sizes
does indeed have the ORDER BY
statement, but it does not affect the end result. 您还可以注意到,
sizes
查询的确具有ORDER BY
语句,但不会影响最终结果。
My initial thought would be that the size
should just be joined
onto the product_size
query. 我最初的想法是将
size
仅joined
到product_size
查询中。 Unfortunately I have no idea on how to do this using includes
. 不幸的是,我不知道如何使用
includes
做到这一点。
Ideally the generated queries would look more like: 理想情况下,生成的查询应类似于:
SELECT "products".* FROM "products"
SELECT "product_sizes".* FROM "product_sizes"
WHERE "product_sizes"."product_id" IN (X, X, X, X)
JOIN "size" ON product_sizes.size_id = sizes.id
ORDER BY `size`.`order`
SELECT "sizes".* FROM "sizes"
WHERE "sizes"."id" IN (X, X, X, X, X, X, X, X) ORDER BY `order` ASC
I went ahead and mapped the sizes
association directly onto products
. 我继续将
sizes
关联直接映射到products
。 Here is what I have: 这是我所拥有的:
product.rb model: product.rb模型:
class Product < ActiveRecord::Base
has_many :product_sizes
has_many :sizes, through: :product_sizes, source: :size
end
product_size.rb model: product_size.rb模型:
class ProductSize < ActiveRecord::Base
belongs_to :product
belongs_to :size
end
size.rb model: size.rb模型:
class Size < ActiveRecord::Base
default_scope -> { order(order: :desc)}
end
seeds.rb file: (you can run rake db:seed to see how it works) seed.rb文件:(您可以运行rake db:seed来查看其工作原理)
# Size.delete_all
# Product.delete_all
# ProductSize.delete_all
size1 = Size.create!(width: 20, height: 5, order: 3)
size2 = Size.create!(width: 30, height: 15, order: 2)
size3 = Size.create!(width: 10, height: 123, order: 1)
size4 = Size.create!(width: 14, height: 12, order: 4)
size5 = Size.create!(width: 24, height: 32, order: 5)
size6 = Size.create!(width: 45, height: 13, order: 7)
size7 = Size.create!(width: 54, height: 31, order: 6)
size8 = Size.create!(width: 35, height: 14, order: 8)
size9 = Size.create!(width: 42, height: 41, order: 9)
size10 = Size.create!(width: 13, height: 54, order: 10)
product1 = Product.create!(title: "Chair", price: 21.00)
product2 = Product.create!(title: "Table", price: 120.00)
product3 = Product.create!(title: "Microwave", price: 34.00)
ProductSize.create!(size: size1, product: product1)
ProductSize.create!(size: size3, product: product1)
ProductSize.create!(size: size5, product: product1)
ProductSize.create!(size: size1, product: product2)
ProductSize.create!(size: size3, product: product2)
ProductSize.create!(size: size4, product: product2)
ProductSize.create!(size: size1, product: product3)
ProductSize.create!(size: size2, product: product3)
ProductSize.create!(size: size3, product: product3)
ProductSize.create!(size: size8, product: product3)
ProductSize.create!(size: size9, product: product3)
ProductSize.create!(size: size10, product: product3)
ProductSize.create!(size: size4, product: product3)
ProductSize.create!(size: size5, product: product3)
ProductSize.create!(size: size6, product: product3)
ProductSize.create!(size: size7, product: product3)
products = Product.includes(:sizes).references(:sizes).order('"sizes"."order" DESC').to_a
products.each do |product|
puts product.title
product.sizes.each { |size| print "#{size.order} " }
puts
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.