# What's the best way to model this?

**URL:** <https://www.ruby-forum.com/t/whats-the-best-way-to-model-this/141374>\
**Category:** Rails\
**Created:** [June 25, 2008, 5:37am UTC](https://www.ruby-forum.com/t/whats-the-best-way-to-model-this/141374 "2008-06-25T05:37:36Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![PeteSalty](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bc79bd/32.png) [@PeteSalty](https://www.ruby-forum.com/u/PeteSalty)\
**Post date:** [June 25, 2008, 5:37am UTC](https://www.ruby-forum.com/t/whats-the-best-way-to-model-this/141374/1 "2008-06-25T05:37:36Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![PeteSalty](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bc79bd/32.png) [@PeteSalty](https://www.ruby-forum.com/u/PeteSalty)\
**Post date:** [June 25, 2008, 7:18pm UTC](https://www.ruby-forum.com/t/whats-the-best-way-to-model-this/141374/2 "2008-06-25T19:18:38Z")

</div>

Any ideas?

---

<div class="post-metadata">

**Author:** ![PeteSalty](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bc79bd/32.png) [@PeteSalty](https://www.ruby-forum.com/u/PeteSalty)\
**Post date:** [June 25, 2008, 10:16pm UTC](https://www.ruby-forum.com/t/whats-the-best-way-to-model-this/141374/3 "2008-06-25T22:16:57Z")

</div>

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 ☹

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

---

<div class="post-metadata">

**Author:** ![PeteSalty](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bc79bd/32.png) [@PeteSalty](https://www.ruby-forum.com/u/PeteSalty)\
**Post date:** [June 26, 2008, 5:44am UTC](https://www.ruby-forum.com/t/whats-the-best-way-to-model-this/141374/4 "2008-06-26T05:44:16Z")

</div>

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

On Jun 25, 1:16 pm, Karl U. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
