has_many things which have many more things which... you get the idea

Say I have the following

class GrandParentThing < ActiveRecord::Base   has_many :parent_things end

class ParentThing < ActiveRecord::Base   has_many :child_things   belongs_to :grand_parent_thing end

class ChildThing < ActiveRecord::Base   belongs_to :parent_thing end

Are there any built-in methods or plugins to help me get all of the child_things that a grand_paraent_thing has?

I know how to do the .find to get the information out using a minimal number of SQL queries but I have a lot of these in my project so I wondered if anyone had packaged it up yet.

TIA, Gareth

Try acts_as_nested_set. It allows you to select all children (and their descendents) with a single query.

http://api.rubyonrails.org/classes/ActiveRecord/Acts/NestedSet/ClassMethods.html

You can use: has_many :grand_child_things, :through => :parent_things

Gareth Adams wrote:

I think acts_as_nested_set will add more functionality than you want. Its intent is to provide the full tree, grand_parent_thing and its parent_things and its child_things in one collection. It doesn't sound like that's the intention here.

Use the :has_many x, :through=>y semantics. In this case you would add:

has_many :child_things, :through=>:parent_things

to the GrandParentClass. With that you can refer to grand_parent_thing.child_things and get all the children.

HTH, AndyV

I think acts_as_nested_set will add more functionality than you want. Its intent is to provide the full tree, grand_parent_thing and its parent_things and its child_things in one collection. It doesn't sound like that's the intention here.

It gives you a full subtree. The OP wanted to "get all of the child_things that a grandparent_thing has" , which if you look at his model structure, means that, given a grandparent, he wants to get all its grandchildren. And acts_as_nested_set will do exactly that.

Use the :has_many x, :through=>y semantics. In this case you would add:

has_many :child_things, :through=>:parent_things

to the GrandParentClass. With that you can refer to grand_parent_thing.child_things and get all the children.

Yes, this will work too. I *think* acts_as_nested_set would be more efficient though, because it is optimized for retrieval--no joins are needed.

-- Mark.

Mark Thomas wrote:

  

I think acts_as_nested_set will add more functionality than you want. Its intent is to provide the full tree, grand_parent_thing and its parent_things and its child_things in one collection. It doesn't sound like that's the intention here.      It gives you a full subtree. The OP wanted to "get all of the child_things that a grandparent_thing has" , which if you look at his model structure, means that, given a grandparent, he wants to get all its grandchildren. And acts_as_nested_set will do exactly that.

Doesn't acts_as_nested_set's all_children() method return all descendants of a given node? Meaning that you would get all parent_things and child_things in the same query?

Also, according to the docs (http://api.rubyonrails.org/classes/ActiveRecord/Acts/NestedSet/ClassMethods.html#M000652), acts_as_nested_set requires a full table rewrite to insert or remove a node.