Has_many, through with nested models?

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?

2010/1/27 lunaclaire [email protected]:

   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

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