2012-06-05 29 views
6

两个特定的记录查找记录我有一个Product模型has_and_belongs_to_many :taxons,我想找到那些特定分类群的所有产品。例如,如果产品属于“Ruby on Rails”和“衬衫”分类群,则我希望该产品能够返回到数据集中,但如果它仅属于“Ruby on Rails”中的而不是 “或‘衬衫’与另一个表

回答

13

我有这个问题而回,幸运的是有一个很好的解决方案。

def self.has_taxons(taxons) 
    id = arel_table[:id] 
    Product.joins(:taxons).where(taxons: { name: taxons }).group(id).having(id.count.eq(taxons.size)) 
end 
+1

一个互联网给你,先生。 –

+0

@RyanBigg也看看这个宝石:https://github.com/ernie/squeel。它在ARel上增加了一层抽象。它允许您构建更简洁/可读的查询。即使在'taxons.name.in taxons'或'taxons.name >> taxons'不超过嵌套哈希好多了,如果你需要超过2个层次的加盟你就会明白这个链接。你可以让你的'having'东西W/O调用'arel_table',如:'有{数量(ID)== some_size}'。 – jdoe

0

假设的表现是不是一个要求:

a = Taxon.find_by_name!('Ruby on Rails').products.pluck(:id) 
b = Taxon.find_by_name!('Shirts').products.where(:id => a) 
1

从@samuel这个答案正是我一直在寻找,但我希望能够仍然提供关键字搜索,同时通过Taxon1和Taxon2和TaxonN过滤。我从不需要进行Taxon1或Taxon2搜索,因此我进行了以下自定义设置。做这件事可能不太方便,但对我来说很好。

我添加了新的产品范围中/app/models/spree/product_decorator.rb

Spree::Product.class_eval do 
    add_search_scope :in_all_taxons do |*taxons| 
     taxons = get_taxons(taxons) 
     id = arel_table[:id] 
     joins(:taxons).where(spree_taxons: { id: taxons }).group(id).having(id.count.eq(taxons.size)) 
    end 
end 

然后通过添加它使用了新的范围给/app/models/spree/base_decorator.rb

Spree::Core::Search::Base.class_eval do 
    def get_base_scope 
     base_scope = Spree::Product.active 
     base_scope = base_scope.in_all_taxons(taxon) unless taxon.blank? 
     base_scope = get_products_conditions_for(base_scope, keywords) 
     base_scope = add_search_scopes(base_scope) 
     base_scope 
    end 
end 

现在我可以使用标准的搜索助手来获取产品(这意味着我仍然可以提供关键字等随着多个分类群):

# taxon_ids is an array of taxon ids 
@searcher = build_searcher(params.merge(:taxon => taxon_ids)) 
@products = @searcher.retrieve_products 

这对我的作品,感到非常痛苦。不过,我打开更好的选择。