使用ActiveRecord通过Rails中的Tag找到所有产品

时间:2010-01-14 00:04:26

标签: sql ruby-on-rails spree has-many

这可能非常简单,但我正在寻找通过标签检索所有产品的最佳方式,可以这么说。这是Spree的,所以我应该坚持他们建模数据的方式。它实际上是ProductTaxon(如类别,品牌等)

因此,如果产品has_and_belongs_to_many :taxons和分类has_and_belongs_to_many :products,通过分类单找到所有产品的最佳方法是什么?

类似的东西:

@taxon = Taxon.find_by_permalink('categories/')
@products = Product.find_by_taxon(@taxon)

...但我不确定最后一种方法是什么(只是组成了名字)。

5 个答案:

答案 0 :(得分:2)

可能你只是简单地说是否只有一个分类

@products = @taxon.products

如果有多个,我们需要稍微不同的方法。但即便如此,你也可以

@products = @taxons.inject([]) {|taxon| taxon.products}

答案 1 :(得分:2)

@taxon = Taxon.find_by_permalink('categories', :include => :products) 

这会急切加载产品,以便您可以通过

访问它们
@taxon.products

没有再次访问数据库。这是使用.products避免N + 1查询问题的更有效形式。

答案 2 :(得分:0)

Taxon.find_by_permalink('categories/').products不会满足吗?

编辑:哦,对于多个分类单元,你可以试试这样的东西:

Product.find(:all, :include => :products_taxons, :conditions => { :products_taxons => {:taxon_id => [1,2,3]} }) # will find products with taxons with id 1, 2 or 3

答案 3 :(得分:0)

我能够在Spree 2.1.0.beta中使用以下自定义工具:

根据这里的答案:Finding records with two specific records in another table

我在/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

这适合我,感觉很轻松。但是,我愿意接受更好的选择。

答案 4 :(得分:0)

如果您想通过标签查找产品,可以使用tagged_with

实施例

Spree::Product.tagged_with("example")

将使用标记"示例"

返回产品

来源:https://github.com/mbleigh/acts-as-taggable-on