2010-01-14 6 views
1

Ceci est probablement quelque chose de très simple mais je cherche le moyen optimal de récupérer tous les produits par Tag, pour ainsi dire. C'est avec Spree, donc je devrais m'en tenir à la façon dont ils ont modélisé leurs données. Il est en fait Product et Taxon (comme catégorie, marque, etc.)Trouver tous les produits par Tag dans Rails avec ActiveRecord

Donc, si le produit has_and_belongs_to_many :taxons et Taxon has_and_belongs_to_many :products, quelle est la meilleure façon de trouver tous les produits par un Taxon?

Quelque chose comme:

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

... mais je ne suis pas sûr ce qui se passe dans cette dernière méthode (juste fait le nom).

Répondre

2

Probablement vous allez dire tout simplement s'il n'y a qu'un seul Taxon

@products = @taxon.products 

S'il y a plusieurs nous exiger une méthode légèrement différente. Mais même alors vous pouvez

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

super basique: p, perdu dedans tout de suite. Merci pour l'aide! –

+3

Cela causera un problème de requête N + 1 – workmad3

+0

Bon appel, je suis rouillé :) –

0

Est-ce que Taxon.find_by_permalink('categories/').products ne suffira pas?

EDIT: Oh, et pour plusieurs taxons, vous pouvez essayer quelque chose comme ceci:

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 
+0

Eh bien, cela va trouver un taxon mais comme il veut trouver tous les produits de Taxon, nous avons besoin d'un peu plus. –

+0

évidemment vous auriez besoin de vérifier que Taxon.find_by_permalink a retourné quelque chose, ou bien utilisez Taxon.find_by_permalink ('categories /'). Try (: products) – psyho

+0

Hmm, je ne vois pas pourquoi cela ne récupère pas tous les produits avec un taxon donné. – psyho

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

Cela hâte-charger les produits afin que vous puissiez y accéder sans elle frapper à nouveau la base de données par

@taxon.products 

. C'est la forme la plus efficace d'utiliser .products qui évite les problèmes de requête N + 1.

+0

merci pour cela, je vais l'utiliser. –

0

j'ai pu obtenir ce travail dans Spree 2.1.0.beta avec les personnalisations suivantes:

Sur la base de la réponse ici: Finding records with two specific records in another table

J'ai ajouté un nouveau champ d'application du produit dans/app/modèles/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 

ensuite utilisé le nouveau champ en l'ajoutant à /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 

Maintenant, je peux utiliser l'assistant de recherche standard pour récupérer les produits (ce qui signifie que je peux encore fournir des mots-clés, etc., ainsi que les multiples taxons):

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

Cela fonctionne pour moi et se sentait assez indolore. Cependant, je suis ouvert à de meilleures options.

Questions connexes