views:

32

answers:

1

I have a contact model, this includes name, address, phone number, etc.

I have a user model which should have_one contact.

I have a Customer model which has_many contacts.

I have a Producer model which has many contacts.

A contact can be only a user, a user and a customer, a user and a producer, or any combination of these three. I also need to be sure that the same contact record is linked when a contact is linked to multiple models for data integrity.

how should I create the associations?

A: 

This looks like a good application for a polymorphic association:

class User < ActiveRecord::Base
  has_one :contact, :as => :contactable
end

class Customer < ActiveRecord::Base
  has_many :contacts, :as => :contactable
end

class Producer < ActiveRecord::Base
  has_many :contacts, :as => :contactable
end

class Contact < ActiveRecord::Base
  belongs_to :contactable, :polymorphic => true
end

EDIT

It seems I didn't read the specs all the way through :) To associate the same contact with multiple Users, Customers, etc, you could use a has_many :through:

class User < ActiveRecord::Base
  has_one :user_contact, :dependent => :destroy
  has_one :contact, :through => :user_contact
end

class Customer < ActiveRecord::Base
  has_many :customer_contacts, :dependent => :destroy
  has_many :contacts, :through => :customer_contacts
end

class Producer < ActiveRecord::Base
  has_many :producer_contacts, :dependent => :destroy
  has_many :contacts, :through => :producer_contacts
end

class UserContact
  belongs_to :user
  belongs_to :contact
end

class CustomerContact
  belongs_to :customer
  belongs_to :contact
end

class ProducerContact
  belongs_to :producer
  belongs_to :contact
end

class Contact < ActiveRecord::Base
  has_many :user_contacts, :dependent => :destroy # might use 'has_one' here depending on your requirements
  has_many :users, :through => :user_contacts
  has_many :customer_contacts, :dependent => :destroy
  has_many :customers, :through => :customer_contacts
  has_many :producer_contacts, :dependent => :destroy
  has_many :producers, :through => :producer_contacts
end

That gives you one join table for each of the three associations. Each Contact can belong to none, one, or many of the three other models by adding rows to the join tables.

zetetic
but then how does a contact belong to a user, a customer, and a producer at the same time. With this wouldn't contact be only associated with a single type?
thargor
Er, yes, that's true. See my edit.
zetetic