# Has\_many things which have many more things which... you get

**URL:** <https://www.ruby-forum.com/t/has-many-things-which-have-many-more-things-which-you-get/112534>\
**Category:** Rails\
**Created:** [August 20, 2007, 6:52pm UTC](https://www.ruby-forum.com/t/has-many-things-which-have-many-more-things-which-you-get/112534 "2007-08-20T18:52:48Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gareth\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/b9bd4f/32.png) [@Gareth\_A](https://www.ruby-forum.com/u/Gareth_A)\
**Post date:** [August 20, 2007, 6:52pm UTC](https://www.ruby-forum.com/t/has-many-things-which-have-many-more-things-which-you-get/112534/1 "2007-08-20T18:52:48Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Gareth\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/b9bd4f/32.png) [@Gareth\_A](https://www.ruby-forum.com/u/Gareth_A)\
**Post date:** [August 20, 2007, 6:58pm UTC](https://www.ruby-forum.com/t/has-many-things-which-have-many-more-things-which-you-get/112534/2 "2007-08-20T18:58:49Z")

</div>

You can use:  
has\_many :grand\_child\_things, :through =\> :parent\_things

---

<div class="post-metadata">

**Author:** ![Gareth\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/b9bd4f/32.png) [@Gareth\_A](https://www.ruby-forum.com/u/Gareth_A)\
**Post date:** [August 21, 2007, 6:24pm UTC](https://www.ruby-forum.com/t/has-many-things-which-have-many-more-things-which-you-get/112534/3 "2007-08-21T18:24:13Z")

</div>

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](http://api.rubyonrails.org/classes/ActiveRecord/Acts/NestedSet/ClassMethods.html)

---

<div class="post-metadata">

**Author:** ![Gareth\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/b9bd4f/32.png) [@Gareth\_A](https://www.ruby-forum.com/u/Gareth_A)\
**Post date:** [September 25, 2007, 11:03pm UTC](https://www.ruby-forum.com/t/has-many-things-which-have-many-more-things-which-you-get/112534/4 "2007-09-25T23:03:33Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Gareth\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/b9bd4f/32.png) [@Gareth\_A](https://www.ruby-forum.com/u/Gareth_A)\
**Post date:** [September 25, 2007, 11:12pm UTC](https://www.ruby-forum.com/t/has-many-things-which-have-many-more-things-which-you-get/112534/5 "2007-09-25T23:12:01Z")

</div>

On Aug 20, 1:00 pm, AndyV [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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.

> 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.

---

<div class="post-metadata">

**Author:** ![Gareth\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/b9bd4f/32.png) [@Gareth\_A](https://www.ruby-forum.com/u/Gareth_A)\
**Post date:** [September 25, 2007, 11:12pm UTC](https://www.ruby-forum.com/t/has-many-things-which-have-many-more-things-which-you-get/112534/6 "2007-09-25T23:12:10Z")

</div>

Mark T. wrote:

> 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](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.
