# Has\_many, through with nested models?

**URL:** <https://www.ruby-forum.com/t/has-many-through-with-nested-models/182363>\
**Category:** Rails\
**Created:** [January 27, 2010, 1:50am UTC](https://www.ruby-forum.com/t/has-many-through-with-nested-models/182363 "2010-01-27T01:50:19Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![lunaclaire](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/f4b2a3/32.png) [@lunaclaire](https://www.ruby-forum.com/u/lunaclaire)\
**Post date:** [January 27, 2010, 1:50am UTC](https://www.ruby-forum.com/t/has-many-through-with-nested-models/182363/1 "2010-01-27T01:50:19Z")

</div>

First the data model:

class Forum \< ActiveRecord::Base  
has\_many :topics, :dependent =\> :destroy, :order =\> ‘created\_at  
desc’  
end

class User \< ActiveRecord::Base  
has\_many :topics, :dependent =\> :destroy  
has\_many :comments, :dependent =\> :destroy  
has\_many :replies, :dependent =\> :destroy  
end

class Topic \< ActiveRecord::Base  
belongs\_to :forum  
belongs\_to :user  
has\_many :comments, :dependent =\> :destroy  
end

class Comment \< ActiveRecord::Base  
belongs\_to :user  
belongs\_to :topic  
has\_many :replies, :dependent =\> :destroy  
end

class Reply \< ActiveRecord::Base  
belongs\_to :user  
belongs\_to :comment  
end

So Users can post Topics to Forums. They can also post Comments to the  
Topics in a Forum. And they can post Replies to the Comments.

I want to be able to get a list of Forums they’ve participated in by  
posting either Topics or Comments or Replies.

I could just create a Membership that would relate a User to a Forum  
whenever they post something, but then I’d need to maintain the  
Membership when/if they delete their last Post/Comment/Reply from a  
given Forum. That seems messy.

what I’m wonder is if I can do something like this:

class User \< ActiveRecord::Base  
has\_many :topics, :dependent =\> :destroy  
has\_many :comments, :dependent =\> :destroy  
has\_many :replies, :dependent =\> :destroy

has\_many :forums, :through =\> :topics, :uniq =\> true  
has\_many :forums, :through =\> :comments, :uniq =\> true  
has\_many :forums, :through =\> :replies, :uniq =\> true

end

I dont think so… Only the Topic model is directly associated with  
the Forum.

Is there a clean way to do a HMT association on multiple, nested  
associations like this?

---

<div class="post-metadata">

**Author:** ![lunaclaire](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/f4b2a3/32.png) [@lunaclaire](https://www.ruby-forum.com/u/lunaclaire)\
**Post date:** [January 27, 2010, 9:54am UTC](https://www.ruby-forum.com/t/has-many-through-with-nested-models/182363/2 "2010-01-27T09:54:18Z")

</div>

2010/1/27 lunaclaire [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> ```
> has_many :replies, :dependent => :destroy
> belongs_to :topic
> 
> ```
> 
> I want to be able to get a list of Forums they’ve participated in by  
> posting either Topics or Comments or Replies.

I am not sure if this will work but could you provide a named\_scope on  
Forum that takes a user id as a parameter, :include topic, user,  
comment and reply, and specify the condition that  
forum.topic.user.id=user\_id OR forum.topic.comment.user.id = user\_id  
OR forum.topic.reply.user.id=user\_id.

I am not sure if the include user will include comment.user and  
reply.user, I am working out of my comfort zone here. If there is not  
a rails way to do it then you could always just write the above as SQL  
though I always try and avoid this.

Colin

---

<div class="post-metadata">

**Author:** ![lunaclaire](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/f4b2a3/32.png) [@lunaclaire](https://www.ruby-forum.com/u/lunaclaire)\
**Post date:** [February 2, 2010, 11:04pm UTC](https://www.ruby-forum.com/t/has-many-through-with-nested-models/182363/3 "2010-02-02T23:04:46Z")

</div>

Thx, Colin. I didnt see your reply, but I got a very similar answer  
today on StackOverflow:

Basically, it looks like this:

class Forum \< ActiveRecord::Base  
has\_many :topics, :dependent =\> :destroy, :order =\> ‘created\_at  
desc’  
named\_scope :user\_posted, lambda {|user|  
{ :joins =\> "JOIN topics t ON t.forum\_id = forums.id " +  
"JOIN comments c ON c.topic\_id = t.id " +  
“JOIN replies r ON r.comment\_id = c.id”,  
:conditions =\> [“t.user\_id = ? OR c.user\_id = ? OR r.user\_id  
= ?”,  
user, user, user],  
:group =\> “forums.id”  
}  
}  
end
