views:

148

answers:

1

Hi,

Let's say you have two models which can be associated in different ways:

A User has many conversations they have created. (one to many) A User has many conversations in which they are involved. (many to many)

My first thought was to store the id of the user who created the conversation in the conversations table, and associate users involved in a conversation in a join table.

class User < ActiveRecord::Base
  has_many :conversations
  has_and_belongs_to_many :conversations
end

class Conversation < ActiveRecord::Base
  belongs_to :user
  has_and_belongs_to_many :users
end

This seems to be asking for trouble though.

What's the right way to do this? Basically I want to be able to utilise user.conversations for those involved in and user.started_conversations for those started by user.

Thanks.

+6  A: 

The key is to not use HABTM (where all relationships are considered simple), but to use has_many, through , with an attribute on the join to indicate the particular join that denotes the starter/initiator of the conversation.

class User < ActiveRecord::Base

  has_many :user_conversations  
  has_many :conversations, :through => :user_conversations
  has_many :initiated_conversations, :through => :user_conversations,
             :source => :conversation, 
             :conditions => ["user_conversations.starter = ?", true]

end

(assuming that you've got a join model called UserConversation with a boolean attribute called starter).

This will let you do things like:

#get conversations users, including the starter
@user.conversations

#get those started by the user, utilizing the attribute in the conditions
@user.initiated_conversations
mylescarrick