What's the best way to model this?

Let's say I have a user model and a contacts model (contacts contains name, phone number, email, etc. of people that the user knows). The models would be

User:

has_many :contacts

Contact:

belongs_to :user

Now let's say I wanted to introduce groups, where the user could place certain contacts into groups. Some contacts would be in multiple groups, others wouldn't be in groups at all. What would be the best way to model this?

I was thinking

User:

has_many :contacts has_many :groups

Groups:

belongs_to :user has_and_belongs_to_many :contacts

Contacts:

belongs_to :user has_and_belongs_to_many :groups

But I'm not sure if this really works. How can I guarantee that a contact in a group really belongs to the user (maybe I can't through the model and need to do it in code but that seems so unRails like).

Dale

Any ideas?

Hi there,

The way I would do it would be like,

Groups:

has_and_belongs_to_many :users

Users:

belongs_to :group has_and_belongs_to_many :contacts,            :class_name => 'User',            :join_table => 'user_contacts',            :association_foreign_key => :contact_id,            :foreign_key => :user_id,            :after_add => :make_contact_to_contact,            :after_remove => :remove_my_contact

with

  # I am there contact so they are my contact   def make_contact_to_contact(contact)     contact.contacts << self unless contact.contacts.include?(self)   end

  # Ok lets no be friends any more :frowning:   def remove_my_contact(contact)     contact.contacts.delete(self) rescue nil   end

In the above I take it that a contact is just another User, hence the user_contact table.

With the above the Group is at the top so you could have something like

user = User.find(:first)

user.groups.first.users --> gives all the users from that users first group, if you get what I mean.

Karl

Karl,

Thanks for the response but actually contacts are not other users - I should have made that clearer. Rather than it being a social-graph type application, it's more like contact management, so contacts belong to the user but are not associated with other users in any way. If they were, your implementation makes perfect sense, but we're actually dealing with 3 models here not 2.

Dale