views:

122

answers:

2

Hi,

I have the following scenario that I want to model the best way for a Rails application.

I have a contact model that belongs to a company. A contact can create an enquiry so contact can have many enquiries. The enquiry can have many messages that can be from and to many contacts. Messages can belong to an enquiry, a company or a contact.

This has been confusing me on how best to model this. Any ideas?

Best regards,

Richard Moss

A: 

It sounds like the confusion is on the messages, rather than the other parts.

I'd go with belongs_to for each of enquiry, company and contact (I'm assuming that you have some messages not associated with enquiries). Then I'd do a custom validation to make sure that at least one of those was specified - but otherwise don't do a validates_presence_of for any of them.

A helper method could ease the pain of finding what a given message is associated with, so you don't have to check each of those three relations looking for one that is not nil.

edebill
+2  A: 

It seems that Message should be polymorphic in this case, since they can belong to many different models. Because contacts can send messages to other contacts, Contact will have two associations with messages, one for sent_messages and the other for received_messages. Message will be tied to a sender through contact_id.

class Contact < ActiveRecord::Base
  belongs_to :company
  has_many :enquiries
  has_many :sent_messages, :class_name => "Message"
  has_many :received_messages, :as => :messageable, :class_name => "Message"
end

class Company < ActiveRecord::Base
  has_many :contacts
  has_many :messages, :as => :messageable
end

class Enquiry < ActiveRecord::Base
  belongs_to :contact
  has_many :messages, :as => :messageable
end

class Message < ActiveRecord::Base
  belongs_to :contact
  belongs_to :messageable, :polymorphic => true
end

This should model your relationship requirements pretty well. If you want to better understand it, the Railscast on Polymorphic Associations might be of some insight as well.

Mike Richards