views:

258

answers:

4

Hi, I have a relatively simple one-to-many relationship and use acts_as_tree to get it organized in the view. It kinda looks like this:

Root

  |_Product 1
  |_Product 2
  |_Category 1.1

        |_Product 3
        |_Product 4
        |_Category 1.1.1

               |_Product 5

The way I set it up is that I list products in the 'show' action of the category. However I can't seem too figure out how to show: Product 1-5 in the 'show' for Category 1, Product 3-5 in Category 1.1 and so on ...

Does anyone have a hint, from where I can pick it up?

Thanks! Val

A: 

You need to use a nested set if you want solve this with acceptable performance (that is, avoid a multitude of separate database lookups to compile the list).

Rails used to have acts _ as _ nested_set built-in, and the explanation of how it works is still very good and quite valid. Today you must use this as a plugin.

However, the default Rails plugin is not very good, which is why several other plugins has been made. I will recommend that you use Awesome Nested Set, which I have used myself with satisfying results.

Nested sets can be a bit hard to understand, but hopefully the first link and the other readme's will explain it to you.

Casper Fabricius
A: 

If you are using awesome_nested_set (recommended, I do), then you can do this:

If Product belongs_to Category:

class Category < ActiveRecord::Base
    def products_in_tree
        Product.all(:joins => :category, :conditions => ['categories.lft >= ? and categories.rgt <= ?', left, right])
    end
end

If Product has_and_belongs_to_many Category (or has_many :through), change the :join to :categories.

Benjamin Curtis
A: 

You may also have a look at the recent ancestry gem designed for high performance when one needs to get all the descendants in one SQL query.

Sergei Kozlov
A: 

@ Caper, Benjamin, Segei - Thanks for the quick reply. I will check out your solutions tomorrow and post my result here. I haven't heard about the ancestry gem yet... sounds really promissing!

Val

val_to_many