Ruby on rails Spree:分类单元之间的交叉点

Ruby on rails Spree:分类单元之间的交叉点,ruby-on-rails,ruby,e-commerce,spree,taxonomy,Ruby On Rails,Ruby,E Commerce,Spree,Taxonomy,是否可以查询属于多个分类单元的产品?就像一个数学交叉点 例如:我出售属于taxon Universities>ASU和taxon Course>Engineering的书籍 我希望能够查询所有属于ASU工程路径的书籍。 差不多 Spree::Product.in_taxon(asu_taxon).in_taxon(eng_taxon) 有几种方法可以做到这一点。我将使用spree沙盒数据,因此如果您感兴趣,可以尝试结果 首先,我们可以遍历所有产品,并使用纯Ruby检查它们的分类: Spree:

是否可以查询属于多个分类单元的产品?就像一个数学交叉点

例如:我出售属于taxon Universities>ASU和taxon Course>Engineering的书籍

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

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

有几种方法可以做到这一点。我将使用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查询即可获得所需的产品


也许有不那么糟糕的方法,但这是我最好的方法

您可以尝试
Spree::Product.joins('internal JOIN Spree\u products\u taxon rails\u JOIN ON(Spree\u products.id=rails\u JOIN.Product\u id)'))。joins('internal JOIN Spree\u taxon rails\u taxon rails\u taxon(rails\u JOIN.taxon\u id=rails\u taxon.id和rails\u taxon.name不在(“Hide”、“Old”))))
我有相同的用例,最后这样做了:

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

希望对你有帮助

很好!你知道为什么没有人对制作一个控制器来处理分类交叉点过滤器感兴趣吗?或者至少是一个扩展?我不知道是否存在这样的扩展。我想这不是很多人需要做的事情。大多数商店只允许人们通过一个分类单元而不是多个分类单元进行浏览。