# Self-referencing relationships

**URL:** <https://www.ruby-forum.com/t/self-referencing-relationships/135869>\
**Category:** Rails\
**Created:** [April 25, 2008, 8:26pm UTC](https://www.ruby-forum.com/t/self-referencing-relationships/135869 "2008-04-25T20:26:29Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ldt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/c0e974/32.png) [@ldt](https://www.ruby-forum.com/u/ldt)\
**Post date:** [April 25, 2008, 8:26pm UTC](https://www.ruby-forum.com/t/self-referencing-relationships/135869/1 "2008-04-25T20:26:29Z")

</div>

I have a question on how to approach a simple self-referencing data  
model in Rails:

I have a table called “relationships”:

create\_table :relationships do |t|  
t.integer :user\_id  
t.integer :is\_relationship\_with  
t.string :relationship

t.timestamps  
end

And a table called “user”

create\_table “users”, :force =\> true do |t|  
t.column :login, :string  
t.column :email, :string  
#… and so on…  
end

A relationship could be one of the following: friend\_of, student\_of,  
parent\_of. Any user should be able to have one or more of these, but  
of course should be defined only once as one of these three options.

My question is, how would I do this in the model? I am assuming it  
would go into my model/relationships.rb file using something like a  
has\_and\_belongs\_to\_many instruction, but not sure how that should look  
given the recursive nature of this data model. Any strategic advice  
would be most appreciated!

Cheers,  
Joe

---

<div class="post-metadata">

**Author:** ![ldt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/c0e974/32.png) [@ldt](https://www.ruby-forum.com/u/ldt)\
**Post date:** [April 25, 2008, 9:48pm UTC](https://www.ruby-forum.com/t/self-referencing-relationships/135869/2 "2008-04-25T21:48:52Z")

</div>

On Apr 25, 11:25 am, Joe L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> A relationship could be one of the following: friend\_of, student\_of,  
> parent\_of. Any user should be able to have one or more of these, but  
> of course should be defined only once as one of these three options.

Just a correction: Any user could have any number of such  
relationships. (Started this question out using my Roles model where  
that would have made more sense…)

And to further clarify my Relationships data:

t.integer :user\_id # is the obvious foreign key back to the user  
table.  
t.integer :is\_relationship # is the foreign key back to the user table  
for whom this relationship is being applied. (name changed slightly  
from earlier post)  
t.string :relationship # can be friend\_of, student\_of, parent\_of.  
replaces the _relationship_ part of the above field.

I can see in my relationships.rb model that this might be a start:

class Relationship \< ActiveRecord::Base  
has\_many :users, :through =\> :relationships  
end

But I’m confused about what to do about the :is\_relationship part, and  
in turn what I would need to put in the user model -  
has\_many :relationships ?

---

<div class="post-metadata">

**Author:** ![ldt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/c0e974/32.png) [@ldt](https://www.ruby-forum.com/u/ldt)\
**Post date:** [April 29, 2008, 5:50am UTC](https://www.ruby-forum.com/t/self-referencing-relationships/135869/3 "2008-04-29T05:50:54Z")

</div>

I was just looking for a solution to this myself! I didn’t find one so  
I had a play, and came up with the following example. It all seemed to  
work quite nicely so I thought I’d post it

## Overview

I’ve used a twitter metaphor with users, followers, and leaders:

I have 2 classes, one called “User”, and one called “UserFollower”  
which is basically a self referential linking table.

In the user\_followers table there is two foreign keys - user\_id and  
follower\_id

## Code

class User \< ActiveRecord::Base  
has\_many :user\_followers  
has\_many :followers, :through =\> :user\_followers

has\_many :user\_leaders, :class\_name =\> “UserFollower”, :foreign\_key  
=\> “follower\_id”  
has\_many :leaders, :through =\> :user\_leaders, :source =\> :user  
end

class UserFollower \< ActiveRecord::Base  
belongs\_to :user  
belongs\_to :follower, :class\_name =\> “User”  
end

## Console Session

> > user = User.create( :name =\> “Jono” )  
> > =\> #\<User id: 1, name: “Jono”, created\_at: “2008-04-29 15:33:02”,  
> > updated\_at: “2008-04-29 15:33:02”\>
> 
> > User.create( :name =\> “David” )  
> > =\> #\<User id: 2, name: “David”, created\_at: “2008-04-29 15:33:13”,  
> > updated\_at: “2008-04-29 15:33:13”\>
> 
> > user.followers  
> > =\> []
> 
> > user.user\_followers.create( :follower =\> User.find(2) )  
> > =\> #\<UserFollower id: 1, user\_id: 1, follower\_id: 2, created\_at:  
> > “2008-04-29 15:34:25”, updated\_at: “2008-04-29 15:34:25”\>
> 
> > user.followers  
> > =\> [#\<User id: 2, name: “David”, created\_at: “2008-04-29 15:33:13”,  
> > updated\_at: “2008-04-29 15:33:13”\>]
> 
> > user = User.find(2)  
> > =\> #\<User id: 2, name: “David”, created\_at: “2008-04-29 15:33:13”,  
> > updated\_at: “2008-04-29 15:33:13”\>
> 
> > user.followers  
> > =\> []
> 
> > user.leaders  
> > =\> [#\<User id: 1, name: “Jono”, created\_at: “2008-04-29 15:33:02”,  
> > updated\_at: “2008-04-29 15:33:02”\>]

---

<div class="post-metadata">

**Author:** ![ldt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/c0e974/32.png) [@ldt](https://www.ruby-forum.com/u/ldt)\
**Post date:** [April 29, 2008, 6:40am UTC](https://www.ruby-forum.com/t/self-referencing-relationships/135869/4 "2008-04-29T06:40:46Z")

</div>

I’ve written a tutorial on this now because it’s such a frequently asked  
question:

> **[frozenplague.net](http://frozenplague.net/2008/04/29/self-referrential-relationships/)**
>
> This domain may be for sale!
