# 2-way associations

**URL:** <https://www.ruby-forum.com/t/2-way-associations/186761>\
**Category:** Rails\
**Created:** [February 25, 2008, 9:19pm UTC](https://www.ruby-forum.com/t/2-way-associations/186761 "2008-02-25T21:19:05Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [February 25, 2008, 9:19pm UTC](https://www.ruby-forum.com/t/2-way-associations/186761/1 "2008-02-25T21:19:05Z")

</div>

Hello,

I was wondering if there is an easy way to handle this N+1 problem.

class Post \< ActiveRecord::Base  
has\_many :comments  
end

class Comment \< ActiveRecord::Base  
belongs\_to :post

def full\_name  
“comment on #{post.title} by #{author}”  
end  
end

Now when I want a post with all its comments, I go:  
p=Post.find(:first, :include =\> :comments)

queries:  
Post Load Including Associations (0.000863) SELECT posts.“id” AS  
t0\_r0, posts.“title” AS t0\_r1, posts.“body” AS t0\_r2, posts.“eated\_at”  
AS t0\_r3, posts.“updated\_at” AS t0\_r4, comments.“id” AS t1\_r0,  
comments.“post\_id” AS t1\_r1, comments.“body” AS t1\_r2,  
coents.“created\_at” AS t1\_r3, comments.“updated\_at” AS t1\_r4 FROM  
posts LEFT OUTER JOIN comments ON comments.post\_id = posts.id

p.comments.first.full\_name

queries:  
Post Load (0.000650) SELECT \* FROM posts WHERE (posts.“id” = 1)

It seems to me it’s a little dumb to re-get the post, since it’s  
already loaded and associated to this comment(since the comment was  
loaded through the post’s association).  
Ofcourse I could use Post.find(:first, :include =\> {:comments  
=\> :post}).  
But it doesn’t feel right since Post is included twice.

Any “good” way to do this?

Thanks.  
Mathijs

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [February 26, 2008, 12:54am UTC](https://www.ruby-forum.com/t/2-way-associations/186761/2 "2008-02-26T00:54:38Z")

</div>

> I was wondering if there is an easy way to handle this N+1 problem.
> 
> class Post \< ActiveRecord::Base  
> has\_many :comments  
> end
> 
> class Comment \< ActiveRecord::Base  
> belongs\_to :post
> 
> def full\_name  
> “comment on #{post.title} by #{author}”  
> end  
> end
> 
> Now when I want a post with all its comments, I go:  
> p=Post.find(:first, :include =\> :comments)

> p.comments.first.full\_name

> Any “good” way to do this?

Well I normally dislike putting text into models. If you want to use  
this for printing in a template, you can puts something liek this in a  
helper:

def full\_name(post)  
“comment on #{post.title} by #{post.comments.first.author}”  
end

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [February 26, 2008, 5:20am UTC](https://www.ruby-forum.com/t/2-way-associations/186761/3 "2008-02-26T05:20:43Z")

</div>

removed\_email\_address@domain.invalid wrote:

> queries:  
> Post Load Including Associations (0.000863) SELECT posts.“id” AS  
> t0\_r0, posts.“title” AS t0\_r1, posts.“body” AS t0\_r2, posts.“eated\_at”  
> AS t0\_r3, posts.“updated\_at” AS t0\_r4, comments.“id” AS t1\_r0,  
> comments.“post\_id” AS t1\_r1, comments.“body” AS t1\_r2,  
> coents.“created\_at” AS t1\_r3, comments.“updated\_at” AS t1\_r4 FROM  
> posts LEFT OUTER JOIN comments ON comments.post\_id = posts.id
> 
> p.comments.first.full\_name
> 
> queries:  
> Post Load (0.000650) SELECT \* FROM posts WHERE (posts.“id” = 1)
> 
> Thanks.  
> Mathijs

I am quite surprised at your findings, I assumed that the association  
from comment to post would have been established with the first  
collection loading (post to comments).

I will have to try this on my machine tomorrow at work but I assumed  
that when an AR collection loads it components, the contained components  
automatically get the container id…

ilan

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [February 26, 2008, 8:37am UTC](https://www.ruby-forum.com/t/2-way-associations/186761/4 "2008-02-26T08:37:54Z")

</div>

Like I said, this is just a basic ‘proof of concept’.  
Ofcourse in this case (almost empty db, sqlite locally) it doesn’t  
matter at all, especially not with 1 comment.

And ofcourse putting text should be in a helper, this is just to  
demonstrate the strange behavior, the actual case needs different  
data(not text) from the parent object.

In real life situations this WILL hurt since it’s a N+1 problem.  
If in my example a certain post has 10000 comments, it will generate  
10001 queries just for this simple bit of code.

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [February 26, 2008, 8:00am UTC](https://www.ruby-forum.com/t/2-way-associations/186761/5 "2008-02-26T08:00:52Z")

</div>

You’re fretting over 0.000650 seconds. Please.
