# Deep nested associations on the same Model

**URL:** <https://www.ruby-forum.com/t/deep-nested-associations-on-the-same-model/174753>\
**Category:** Rails\
**Created:** [September 1, 2009, 5:42pm UTC](https://www.ruby-forum.com/t/deep-nested-associations-on-the-same-model/174753 "2009-09-01T17:42:08Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jbhruby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/439d5e/32.png) [@jbhruby](https://www.ruby-forum.com/u/jbhruby)\
**Post date:** [September 1, 2009, 5:42pm UTC](https://www.ruby-forum.com/t/deep-nested-associations-on-the-same-model/174753/1 "2009-09-01T17:42:08Z")

</div>

This could be a lot simpler than I think and I’m just missing something  
obvious!

I’m working on a creative collaboration app whereby one user could  
submit a Story and this can then be forked by another user and worked on  
seperately. To acheive this I have a has\_many association within the  
same Story model as such:

class Story \< ActiveRecord::Base

has\_many :forked\_stories, :class\_name =\> ‘Story’, :foreign\_key =\>  
:parent\_story\_id

belongs\_to :parent\_story

end

In this way if a single story is an original it’s parent\_story\_id will  
be nil. Similarly, if I call @story.forked\_stories I can get a  
collection of all the stories that have been forked from the current  
one, or @story.parent\_story will return the story from which it has been  
forked.

What I want is to be able to return all the forked\_stories and their  
forked\_stories for a given Story and I’m finding this very difficult  
since they’re all based on the same model. I keep running into dead  
ends. If I can return them to a certain depth as well that’d be great,  
so I’ve been trying to write a method that accepts a depth parameter but  
the crazy loops are frying my brain.

Perhaps there’s something I can do with routes that would solve the  
problem?

---

<div class="post-metadata">

**Author:** ![jbhruby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/439d5e/32.png) [@jbhruby](https://www.ruby-forum.com/u/jbhruby)\
**Post date:** [September 1, 2009, 6:54pm UTC](https://www.ruby-forum.com/t/deep-nested-associations-on-the-same-model/174753/2 "2009-09-01T18:54:35Z")

</div>

Jon H. wrote:

> This could be a lot simpler than I think and I’m just missing something  
> obvious!
> 
> I’m working on a creative collaboration app whereby one user could  
> submit a Story and this can then be forked by another user and worked on  
> seperately. To acheive this I have a has\_many association within the  
> same Story model as such:
> 
> class Story \< ActiveRecord::Base
> 
> has\_many :forked\_stories, :class\_name =\> ‘Story’, :foreign\_key =\>  
> :parent\_story\_id
> 
> belongs\_to :parent\_story
> 
> end
> 
> In this way if a single story is an original it’s parent\_story\_id will  
> be nil. Similarly, if I call @story.forked\_stories I can get a  
> collection of all the stories that have been forked from the current  
> one, or @story.parent\_story will return the story from which it has been  
> forked.

So you have a tree structure of arbitrary depth?

> What I want is to be able to return all the forked\_stories and their  
> forked\_stories for a given Story and I’m finding this very difficult  
> since they’re all based on the same model. I keep running into dead  
> ends. If I can return them to a certain depth as well that’d be great,  
> so I’ve been trying to write a method that accepts a depth parameter but  
> the crazy loops are frying my brain.

There is a less obvious but ultimately much simpler way to do this. Use  
a nested-set data structure, which will make what you’re talking about  
pretty easy. The awesome\_nested\_set plugin would be just what you need.

> Perhaps there’s something I can do with routes that would solve the  
> problem?

No. Your issues have to do with data structure, not routing.

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![jbhruby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/439d5e/32.png) [@jbhruby](https://www.ruby-forum.com/u/jbhruby)\
**Post date:** [September 2, 2009, 12:04pm UTC](https://www.ruby-forum.com/t/deep-nested-associations-on-the-same-model/174753/3 "2009-09-02T12:04:38Z")

</div>

On Sep 1, 5:42 pm, Jon H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> What I want is to be able to return all the forked\_stories and their  
> forked\_stories for a given Story and I’m finding this very difficult  
> since they’re all based on the same model. I keep running into dead  
> ends. If I can return them to a certain depth as well that’d be great,  
> so I’ve been trying to write a method that accepts a depth parameter but  
> the crazy loops are frying my brain.

As far as I can tell you have an algorithmical difficulty, not one  
related to Rails. To get back all the forked stories for a given story  
the following code snippet would do the job:

def fork\_tree  
forked = forked\_stories  
forked\_from\_children = forked.inject([]) do |fstories, fstory|  
fstories + fstory.fork\_tree  
end  
forked + forked\_from\_children  
end

(you can see the whole thing here: [story.rb · GitHub](http://gist.github.com/179186))

Note1: This has been tested under Ruby, not Rails  
Note2: The method is badly named, since it just returns an array, not  
a tree-like structure of all the stories forked directly from the  
story or from its children, or grandchildren, etc.

Hope this helps,  
Bálint

---

<div class="post-metadata">

**Author:** ![jbhruby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/439d5e/32.png) [@jbhruby](https://www.ruby-forum.com/u/jbhruby)\
**Post date:** [September 2, 2009, 12:12pm UTC](https://www.ruby-forum.com/t/deep-nested-associations-on-the-same-model/174753/4 "2009-09-02T12:12:16Z")

</div>

Balint E. wrote:

> On Sep 1, 5:42ï¿½pm, Jon H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > What I want is to be able to return all the forked\_stories and their  
> > forked\_stories for a given Story and I’m finding this very difficult  
> > since they’re all based on the same model. I keep running into dead  
> > ends. If I can return them to a certain depth as well that’d be great,  
> > so I’ve been trying to write a method that accepts a depth parameter but  
> > the crazy loops are frying my brain.
> 
> As far as I can tell you have an algorithmical difficulty, not one  
> related to Rails. To get back all the forked stories for a given story  
> the following code snippet would do the job:
> 
> def fork\_tree  
> forked = forked\_stories  
> forked\_from\_children = forked.inject([]) do |fstories, fstory|  
> fstories + fstory.fork\_tree  
> end  
> forked + forked\_from\_children  
> end
> 
> (you can see the whole thing here: [story.rb · GitHub](http://gist.github.com/179186))
> 
> Note1: This has been tested under Ruby, not Rails  
> Note2: The method is badly named, since it just returns an array, not  
> a tree-like structure of all the stories forked directly from the  
> story or from its children, or grandchildren, etc.
> 
> Hope this helps,  
> Bï¿½lint

Note 3: Unless the whole array has already been loaded into memory,  
that’s horribly inefficient. Nested sets are the way to go here.

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![jbhruby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/439d5e/32.png) [@jbhruby](https://www.ruby-forum.com/u/jbhruby)\
**Post date:** [September 2, 2009, 9:58pm UTC](https://www.ruby-forum.com/t/deep-nested-associations-on-the-same-model/174753/5 "2009-09-02T21:58:19Z")

</div>

> Note 3: Unless the whole array has already been loaded into memory,  
> that’s horribly inefficient. Nested sets are the way to go here.
> 
> ## Best,
> 
> ## Marnen Laibow-Koserhttp://www.marnen.org removed\_email\_address@domain.invalid
> 
> Posted viahttp://www.ruby-forum.com/.

Seems interesting, could you sketch up how that would work?

Balint

---

<div class="post-metadata">

**Author:** ![jbhruby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/439d5e/32.png) [@jbhruby](https://www.ruby-forum.com/u/jbhruby)\
**Post date:** [September 3, 2009, 12:38am UTC](https://www.ruby-forum.com/t/deep-nested-associations-on-the-same-model/174753/6 "2009-09-03T00:38:17Z")

</div>

Balint E. wrote:

> > Note 3: Unless the whole array has already been loaded into memory,  
> > that’s horribly inefficient. ï¿½Nested sets are the way to go here.
> > 
> > ## Best,
> > 
> > ## Marnen Laibow-Koserhttp://www.marnen.org removed\_email\_address@domain.invalid
> > 
> > Posted viahttp://www.ruby-forum.com/.
> 
> Seems interesting, could you sketch up how that would work?

There are plenty of good articles available on nested sets (notably  
those by Joe Celko and Vadim Tropashko). Check 'em out, and also look  
at the awesome\_nested\_set rdoc!

> Balint

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

Best
