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”
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?
You’ll need a many-many relationship with User to itself. You use two
tables for this kind of relationship:
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
Just as you wuold use ‘belongs to’ and ‘has many’ in your model, you
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)
(I may be wrong!)