# Representing relationships between model objects

**URL:** <https://www.ruby-forum.com/t/representing-relationships-between-model-objects/73869>\
**Category:** Rails\
**Created:** [February 26, 2006, 7:21pm UTC](https://www.ruby-forum.com/t/representing-relationships-between-model-objects/73869 "2006-02-26T19:21:53Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![SBSBSB](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ecccb3/32.png) [@SBSBSB](https://www.ruby-forum.com/u/SBSBSB)\
**Post date:** [February 26, 2006, 7:21pm UTC](https://www.ruby-forum.com/t/representing-relationships-between-model-objects/73869/1 "2006-02-26T19:21:53Z")

</div>

I’m a little stumped on how to approach the subject of representing  
relationships between a single model object.

Basically, I want a User to be able to mark others as Friends,  
Contacts, etc. The caveat is that User A can mark User B as a Friend  
but that doesn’t mean User A is marked as a friend by User B. It can  
either be a one-way relationship or two-way relationship.

Right now I’m confused as to whether there is a “proper” way to do  
this. I’m looking at Single Table Inheritance, HABTM, and now the new  
Polymorphic Associations in Edge Rails.

The main thing that’s confusing me is that when marking someone as  
Friend, you will have to reference the “user\_id” of both User A and  
User B with a foreign key, but I don’t know how to sort that out.

Sorry if this question is vague but my understanding of accomplishing  
this in rails is even vaguer. However, most of the examples I see  
involve defining relationships between two different models such as  
Products, LineItems, and Orders or something like that.

Sam

---

<div class="post-metadata">

**Author:** ![SBSBSB](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ecccb3/32.png) [@SBSBSB](https://www.ruby-forum.com/u/SBSBSB)\
**Post date:** [February 27, 2006, 2:54am UTC](https://www.ruby-forum.com/t/representing-relationships-between-model-objects/73869/2 "2006-02-27T02:54:11Z")

</div>

Hi !

2006/2/26, SB [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Basically, I want a User to be able to mark others as Friends,  
> Contacts, etc. The caveat is that User A can mark User B as a Friend  
> but that doesn’t mean User A is marked as a friend by User B. It can  
> either be a one-way relationship or two-way relationship.

I would go with a HABTM relationship, but with a full model in the  
middle.

class User \< ActiveRecord::Base  
has\_many :relationships

def make\_friend\_of!(name)  
target = User.find\_by\_name(name)  
raise “No person by that name” unless target

```
self.relationships.create(:target => target)

```

end  
end

class Relationship  
belongs\_to :target  
end

user = User.new(:name =\> ‘Francois’)  
user.make\_friend\_of!(‘John’)

That’s the way I would implement it. Of course, I don’t know all your  
requirements, so I can’t really say it is the best way.

Hope that helps !

---

<div class="post-metadata">

**Author:** ![SBSBSB](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ecccb3/32.png) [@SBSBSB](https://www.ruby-forum.com/u/SBSBSB)\
**Post date:** [February 27, 2006, 3:15am UTC](https://www.ruby-forum.com/t/representing-relationships-between-model-objects/73869/3 "2006-02-27T03:15:27Z")

</div>

That’s similar to what I was thinking but then I don’t understand how  
you can map clarify that one User is the owner of the relationship and  
the other User is classified under the relationship because linking  
them by foreign\_key, they would both be “user\_id”.

After sleeping on it, I’m thinking of going with two Single Table  
Inheritances. One is Friends and Another is Groups. Friends will  
have various “types” and each User can aggregate their Friends in  
Groups. It would function as a “join table” but allow more features.  
That way I can model one way relationships.

Such as:  
John =\> Mary’s Friend  
Mary =\> John’s Contact

Polymorphic Associations look promising but I’ll need to see more  
documentation before I can even explore it as an option.

Thanks for the response!  
Sam

---

<div class="post-metadata">

**Author:** ![SBSBSB](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ecccb3/32.png) [@SBSBSB](https://www.ruby-forum.com/u/SBSBSB)\
**Post date:** [February 27, 2006, 3:38am UTC](https://www.ruby-forum.com/t/representing-relationships-between-model-objects/73869/4 "2006-02-27T03:38:03Z")

</div>

You can do this in several ways. The trick is that you can tell Rails to  
use a different name for the field instead of the default one based on  
the model class. That will support one-way relationships, or two-way if  
you make links in both directions There is a good description of how to  
do that at the bottom of this wiki page:  
[http://wiki.rubyonrails.org/rails/pages/HowToCreateASelfReferentialManyToManyRelationship](http://wiki.rubyonrails.org/rails/pages/HowToCreateASelfReferentialManyToManyRelationship)

If you are brave enough to try Edge Rails, you can do something similar  
with the has\_many :through association, otherwise known as join models.  
This is probably the way to go if you want to pursue your open-ended set  
of relationship types. The schema-safe way to do that is to set up a  
3-way join between user1, user2, and call it a role. The role table  
would have a name and maybe other fields that describe things about the  
relationship. That way you can add new roles to the app without having  
to create a new model class or modify the schema. Hmm, I should  
probably write something up about how to do this with some code  
examples.

–josh

SB wrote:

> That’s similar to what I was thinking but then I don’t understand how  
> you can map clarify that one User is the owner of the relationship and  
> the other User is classified under the relationship because linking  
> them by foreign\_key, they would both be “user\_id”.
> 
> After sleeping on it, I’m thinking of going with two Single Table  
> Inheritances. One is Friends and Another is Groups. Friends will  
> have various “types” and each User can aggregate their Friends in  
> Groups. It would function as a “join table” but allow more features.  
> That way I can model one way relationships.
> 
> Such as:  
> John =\> Mary’s Friend  
> Mary =\> John’s Contact
> 
> Polymorphic Associations look promising but I’ll need to see more  
> documentation before I can even explore it as an option.
> 
> Thanks for the response!  
> Sam
