views:

103

answers:

3

This is probably something very simple but I'm looking for the optimal way of retrieving all Products by Tag, so to speak. This is with Spree, so I should stick to the way they have modeled their data. It's actually Product and Taxon (like category, brand, etc.)

So if Product has_and_belongs_to_many :taxons and Taxon has_and_belongs_to_many :products, what's the best way to find all products by a Taxon?

Something like:

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

... but I'm not sure what goes into that last method (just made up the name).

A: 

Won't Taxon.find_by_permalink('categories/').products suffice?

EDIT: Oh and for multiple taxons you could try something like this:

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
psyho
Well, that will find a Taxon but since he wants to find all products by Taxon we need a little more.
Chuck Vose
obviously you'd need to check that Taxon.find_by_permalink returned something, or alternatively use Taxon.find_by_permalink('categories/').try(:products)
psyho
Hmm, I don't see why that does not retrieve all products with a given taxon.
psyho
+1  A: 

Probably you're going to just simply say if there's only one Taxon

@products = @taxon.products

If there's multiple we require a slightly different method. But even then you could just

@products = @taxons.inject([]) {|taxon| taxon.products}
Chuck Vose
super basic :p, lost in it all right now. thanks for the help!
viatropos
This will cause an N+1 query problem
workmad3
Good call, I'm rusty :)
Chuck Vose
+1  A: 
@taxon = Taxon.find_by_permalink('categories', :include => :products) 

This will eager-load the products so you can access them through

@taxon.products

without it hitting the database again. This is the more efficient form of just using .products that avoids N+1 query problems.

workmad3
thank you for that, I'm going to use this.
viatropos