2014-04-01 32 views
0

是否可以查询属于多个分类群的产品?就像一个数学交集。Spree:分类群之间的交集

例如:我销售的图书属于类群大学> ASU,属于类群课程>工程

我希望能够查询属于ASU工程路径的所有书籍。 类似于

Spree::Product.in_taxon(asu_taxon).in_taxon(eng_taxon) 

回答

1

有几种方法可以做到这一点。我将使用spree沙盒数据,因此如果您有兴趣,您可以尝试结果。

首先,我们可以通过所有的产品迭代,并使用检查他们的分类群的纯Ruby:

Spree::Product.all.select do |product| 
    taxon_names = product.taxons.map(&:name) 
    taxon_names.include?("Rails") && taxon_names.include?("Bags") 
end 

这样做的缺点是,它必须检索所有的产品从数据库中,然后将所有的他们的分类单独查询。如果你有相当数量的产品,它会很慢。

我们可以做出更好一点有:

Spree::Product.joins(:taxons).includes(:taxons).where(spree_taxons: { name: ["Rails", "Bags"]}).all.select do |product| 
    taxon_names = product.taxons.map(&:name) 
    taxon_names.include?("Rails") && taxon_names.include?("Bags") 
end 

这只会属于这两个分类群中的一个产品,并使用单个查询检索所有类群数据。它会快得多,但我们可以做得更好......有点......

您可以使用SQL连接为了多次连接表,以减少这个查询到一个查询检索所有的要记录:

Spree::Product 
    .joins('INNER JOIN spree_products_taxons rails_join ON (spree_products.id = rails_join.product_id)') 
    .joins('INNER JOIN spree_taxons rails_taxon ON (rails_join.taxon_id = rails_taxon.id AND rails_taxon.name == "Rails")') 
    .joins('INNER JOIN spree_products_taxons bags_join ON (spree_products.id = bags_join.product_id)') 
    .joins('INNER JOIN spree_taxons bags_taxon ON (bags_join.taxon_id = bags_taxon.id AND bags_taxon.name == "Bags")') 

这是一个有点难看,但它是获取数据的最快方法,因为你只能得到你想要一个SQL查询的产品。

可能有更少的坏方法来做到这一点,但这是我拥有的最好的方法!

+0

真好!你知道为什么没有人有兴趣制作控制器来处理分类群交叉过滤器吗?或者至少是一个扩展? – alexandrecosta

+0

我不知道这样的扩展名是否存在。我想这不是很多人需要做的事情。大多数商店只让人们通过一个单一的分类单元浏览, – gmacdougall

0

你可以尝试Spree::Product.joins('INNER JOIN spree_products_taxons rails_join ON (spree_products.id = rails_join.product_id)').joins('INNER JOIN spree_taxons rails_taxon ON (rails_join.taxon_id = rails_taxon.id AND rails_taxon.name NOT IN ("Hide", "Old"))')

0

我有同样的使用情况下,最终这样做:

Product.joins(:classifications) 
    .where(classifications: {taxon_id: taxon_ids}) 
    .group('products.id') 
    .having('COUNT("products"."id") = ?', taxon_ids.count) 

希望它可以帮助