私はそのProduct
モデルを持っていますhas_and_belongs_to_many :taxons
、そして私は特定の分類群にあるすべての製品を見つけたいです。
たとえば、商品が「Ruby on Rails」と「Shirts」の両方の分類群に属している場合、その商品をデータセットに返す必要がありますが、「RubyonRails」または「Shirts」のいずれかにのみ属している場合はそうではありません。
私はそのProduct
モデルを持っていますhas_and_belongs_to_many :taxons
、そして私は特定の分類群にあるすべての製品を見つけたいです。
たとえば、商品が「Ruby on Rails」と「Shirts」の両方の分類群に属している場合、その商品をデータセットに返す必要がありますが、「RubyonRails」または「Shirts」のいずれかにのみ属している場合はそうではありません。
私はしばらく前にこの問題を抱えていました、ありがたいことに素晴らしい解決策があります。
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
@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
これは私にとってはうまくいき、かなり痛みを感じませんでした。しかし、私はより良い選択肢を受け入れています。
パフォーマンスが要件ではないと仮定します。
a = Taxon.find_by_name!('Ruby on Rails').products.pluck(:id)
b = Taxon.find_by_name!('Shirts').products.where(:id => a)