# A User to User Relationship

**URL:** <https://www.ruby-forum.com/t/a-user-to-user-relationship/72160>\
**Category:** Rails\
**Created:** [October 15, 2006, 12:13am UTC](https://www.ruby-forum.com/t/a-user-to-user-relationship/72160 "2006-10-15T00:13:15Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![shoxz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/9de0a6/32.png) [@shoxz](https://www.ruby-forum.com/u/shoxz)\
**Post date:** [October 15, 2006, 12:13am UTC](https://www.ruby-forum.com/t/a-user-to-user-relationship/72160/1 "2006-10-15T00:13:15Z")

</div>

Hi,

I’m trying to do a project where each User has many Friends and each  
Friend has many Users. Therfore, each person can have multiple friends  
and each friend is associated with multiple users.

The interesting thing is that a Friend is just another User.

I don’t think I need a Friend model, but what I need is to create a join  
table that has a :user\_id and a :friend\_id (which is another :user\_id).  
I’m not quite sure how to do that without creating a model for Friend.

Am I on the right page or would someone do this differently?

Any thoughts would be greatfully appreciated.

S

---

<div class="post-metadata">

**Author:** ![shoxz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/9de0a6/32.png) [@shoxz](https://www.ruby-forum.com/u/shoxz)\
**Post date:** [October 15, 2006, 2:05am UTC](https://www.ruby-forum.com/t/a-user-to-user-relationship/72160/2 "2006-10-15T02:05:13Z")

</div>

I haven’t actually tested this… but it seems to me like you could just  
declare within User that User has\_and\_belongs\_to\_many :users

This would probably create the join table, which would just be user to  
user  
pairings. Again, I haven’t actually tested this, but I don’t see why it  
wouldn’t work the same as usual.

Hopefully that helped a little,  
Tyler P.

On 10/14/06, Shawn Szauksztun-Zvinis [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![shoxz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/9de0a6/32.png) [@shoxz](https://www.ruby-forum.com/u/shoxz)\
**Post date:** [October 15, 2006, 2:07am UTC](https://www.ruby-forum.com/t/a-user-to-user-relationship/72160/3 "2006-10-15T02:07:14Z")

</div>

You’ll need a many-many relationship with User to itself. You use two  
tables for this kind of relationship:

- users  
and
- user\_user

user\_user has no id column, but does have user\_one\_id and user\_two\_id  
columns. It’s basically a map of friends:

user id=1 is friends with user id=2  
user id=1 is friends with user id=3  
user id=2 is friends with user id=4

etc.

Just as you wuold use ‘belongs to’ and ‘has many’ in your model, you  
use:

has\_and\_belongs\_to\_many :users, :join\_table =\> “user\_user”

Rails should then give you nice friendly access to your friends. You  
don’t even need to define a single reference in the user table! I  
haven’t used it myself yet, but I believe you’ll get access to the  
friends as an array :-

my\_user = User.find(:first)  
my\_user.users

(I may be wrong!)

Ben

---

<div class="post-metadata">

**Author:** ![shoxz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/9de0a6/32.png) [@shoxz](https://www.ruby-forum.com/u/shoxz)\
**Post date:** [October 15, 2006, 11:28am UTC](https://www.ruby-forum.com/t/a-user-to-user-relationship/72160/4 "2006-10-15T11:28:08Z")

</div>

I see where you’re going with this, but rails refuses to recognize  
user\_one\_id and user\_two\_id. It’s searching for user\_id in user\_user. I  
tried to overwrite this in the model with :foreign\_key and  
:association\_foreign\_key, but no luck.

The code I’m using to create the new friend is:

user = User.find(:first)  
user.users \<\< User.find\_by\_display\_name(“blahblah”)

This adds “a” user to to the user\_user table only if it has the field  
user\_id and leaves the other field which would hold the second users  
user\_id as NULL. Now if you try to add that as :user\_two\_id it thinks  
you’re talking about the original User model and returns a :user\_two\_id  
not found in Users.

I think we’re on the right page, but something’s missing.

Any thoughts anyone?

Thanks again.

Ben wrote:

> You’ll need a many-many relationship with User to itself. You use two  
> tables for this kind of relationship:
> 
> - users  
> and
> - user\_user
> 
> user\_user has no id column, but does have user\_one\_id and user\_two\_id  
> columns. It’s basically a map of friends:
> 
> user id=1 is friends with user id=2  
> user id=1 is friends with user id=3  
> user id=2 is friends with user id=4
> 
> etc.
> 
> Just as you wuold use ‘belongs to’ and ‘has many’ in your model, you  
> use:
> 
> has\_and\_belongs\_to\_many :users, :join\_table =\> “user\_user”
> 
> Rails should then give you nice friendly access to your friends. You  
> don’t even need to define a single reference in the user table! I  
> haven’t used it myself yet, but I believe you’ll get access to the  
> friends as an array :-
> 
> my\_user = User.find(:first)  
> my\_user.users
> 
> (I may be wrong!)
> 
> Ben

---

<div class="post-metadata">

**Author:** ![shoxz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/9de0a6/32.png) [@shoxz](https://www.ruby-forum.com/u/shoxz)\
**Post date:** [October 15, 2006, 12:06pm UTC](https://www.ruby-forum.com/t/a-user-to-user-relationship/72160/5 "2006-10-15T12:06:51Z")

</div>

As usual, shortly after posting, I’ve come up with something. I think  
it’s because I’m coding at 3:00am in the morning and missing stuff I  
should have caught instantly.

Here’s the solution if anyone cares:

class User \< ActiveRecord::Base

has\_and\_belongs\_to\_many :users, :join\_table =\> “friends”,  
:association\_foreign\_key =\> “user\_two\_id”, :foreign\_key =\> “user\_one\_id”

end

If you don’t manually set the associations and keys, there’s no way this  
would work for a one-to-one many-to-many relationship in the same table.  
Rails get’s lost into trying to figure out why it’s seeing twins and why  
it can’t distinguish the difference between the two.

I said before that I’m injecting the friends as:

user array \<\< new friend

Doing this adds User 2 as a friend of User 1. If I look up User 2’s  
friends I get NIL. How do I make this relationship go both ways? That if  
User 1 adds User 2, User 1 gets added to the array of friends in User 2?

Shawn Szauksztun-Zvinis wrote:

> I see where you’re going with this, but rails refuses to recognize  
> user\_one\_id and user\_two\_id. It’s searching for user\_id in user\_user. I  
> tried to overwrite this in the model with :foreign\_key and  
> :association\_foreign\_key, but no luck.
> 
> The code I’m using to create the new friend is:
> 
> user = User.find(:first)  
> user.users \<\< User.find\_by\_display\_name(“blahblah”)
> 
> This adds “a” user to to the user\_user table only if it has the field  
> user\_id and leaves the other field which would hold the second users  
> user\_id as NULL. Now if you try to add that as :user\_two\_id it thinks  
> you’re talking about the original User model and returns a :user\_two\_id  
> not found in Users.
> 
> I think we’re on the right page, but something’s missing.
> 
> Any thoughts anyone?
> 
> Thanks again.
> 
> Ben wrote:
> 
> > You’ll need a many-many relationship with User to itself. You use two  
> > tables for this kind of relationship:
> > 
> > - users  
> > and
> > - user\_user
> > 
> > user\_user has no id column, but does have user\_one\_id and user\_two\_id  
> > columns. It’s basically a map of friends:
> > 
> > user id=1 is friends with user id=2  
> > user id=1 is friends with user id=3  
> > user id=2 is friends with user id=4
> > 
> > etc.
> > 
> > Just as you wuold use ‘belongs to’ and ‘has many’ in your model, you  
> > use:
> > 
> > has\_and\_belongs\_to\_many :users, :join\_table =\> “user\_user”
> > 
> > Rails should then give you nice friendly access to your friends. You  
> > don’t even need to define a single reference in the user table! I  
> > haven’t used it myself yet, but I believe you’ll get access to the  
> > friends as an array :-
> > 
> > my\_user = User.find(:first)  
> > my\_user.users
> > 
> > (I may be wrong!)
> > 
> > Ben

---

<div class="post-metadata">

**Author:** ![shoxz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/9de0a6/32.png) [@shoxz](https://www.ruby-forum.com/u/shoxz)\
**Post date:** [October 17, 2006, 2:16am UTC](https://www.ruby-forum.com/t/a-user-to-user-relationship/72160/6 "2006-10-17T02:16:36Z")

</div>

I have done a similar thing, and I created a friendship model for this.

The main reason is that in my system a friendship goes through multiple  
stages. One user initiates a friendship request or invite, and the  
other user either accepts (establishes a friendship) or rejects the  
offer. Then at any time, one user might terminate the friendship. I  
feel there is enough information here to warrant another model, and a  
few columns in the friendship table.

I always query this model from the perspective of the active user (I  
provide the user\_id as a query condition), which avoids having to deal  
with queries that include the user table twice. Then again, I’m kind of  
a newbie, and maybe avoiding the problem is not your preference. 🙂

I don’t have my code on me, but I hope this is a little helpful.

Chris
