Topic: can has_and_belongs_to_many reference itself?

Hi

I have a case where users have friends, but friends are really users.

I'd like to have a users_friends table with user_id and friend_id, but friend_id is really an alias for user_id and there is no friend table.

Can this work?

I'm thinking it would be something like this in user.rb

has_and_belongs_to_many :friends,
   :class_name => "User",
   :foreign_key => "friend_id"

but really its the users that have many friends.

thanks
Jeff

Last edited by jwattenmaker (2007-03-26 11:56:43)

Re: can has_and_belongs_to_many reference itself?

Looks like you're on the right track. Try "association_foreign_key" option instead of just "foreign_key". Also rename the join table to friends_users (it must be in alphabetical order). I think it will work then.

Railscasts - Free Ruby on Rails Screencasts

Re: can has_and_belongs_to_many reference itself?

Hi Ryan

thanks for the info, I tried it and so far I get the following error when I try to access it.

Mysql::Error: #42S02Table 'sportsgroov_development.users_users' doesn't exist: SHOW FIELDS FROM users_users

I do have a friends_users table, not a users_users table. I could rename it, but then I'm not sure if the id's inside would be accurate. Maybe something else is wrong.

here is my code so far.

In my controller I do this, and get no complaints.

    # find all friends
    @friends = @user.friends

In my view I do this and get the error

        <% @friends.each do |friend| %>

my model for user has this. And I don't have a friends.rb or a friends_user.rb
  has_and_belongs_to_many :friends,
    :class_name => "User",
    :association_foreign_key => "friend_id"

thanks

Jeff

Re: can has_and_belongs_to_many reference itself?

Oh, you need to specify the join table as well:

  has_and_belongs_to_many :friends,
    :class_name => "User",
    :association_foreign_key => "friend_id",
    :join_table => "friends_users"

Railscasts - Free Ruby on Rails Screencasts

Re: can has_and_belongs_to_many reference itself?

thanks Ryan, as usual it works great

Re: can has_and_belongs_to_many reference itself?

In a situation like this, how would one go about adding a friend?

<%= friend.name %> <%= link_to "add friend", add_friend_user_path(friend.id) %>

creates a link to http://localhost:3000/users/2;add_friend

where params[:id] grabs the 2 and the sends it to the add_friend action.  From there, how do you add an entry to the friends_users table?  Normally I would use @friends = Friend.new but of course there's no friend controller or model.

Re: can has_and_belongs_to_many reference itself?

You could do this:

current_user.friends << Friend.find(params[:id])

You may want to change the HABTM association to has_many :through. This way you can have a full out "Friendship" join model which has its own controller. Then you don't have to create a separate action in the users controller. If you're adding a user as a friend, what you're really doing is creating a Friendship join.

Railscasts - Free Ruby on Rails Screencasts

Re: can has_and_belongs_to_many reference itself?

Thanks Ryan.  I think for my purpose, since I don't have anything in the table besides user_id and friend_id that I'll just stick to HABTM.  But your code works and I really appreciate you helping me out!