Forum: Ruby on Rails Self-Referential Many-To-Many relationships where the relati

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Jordan F. (Guest)
on 2006-03-25 07:38
(Received via mailing list)
Trying to model a bunch of users that have friends that are other
users. clearly a job for has_and_belongs_to_many, but the trick is,
they have ratings for their friends. I have gone through the Rails
Recipes book, and it seems like I'm trying to combine the
self-referential many-to-many recipe (12) and the many to many
relationships where the relationship itself has data recipe (16). So
users have unique names, and friendships have user_id's, friend_id's,
and ratings. And here's the model code:

class User < ActiveRecord::Base
  has_and_belongs_to_many :all_friends,
    :class_name => "User",
    :join_table => "friendships",
    :foreign_key => "user_id",
    :association_foreign_key => "friend_id"

  has_and_belongs_to_many :close_friends,
    :class_name => "User",
    :join_table => "friendships",
    :foreign_key => "user_id",
    :association_foreign_key => "friend_id",
    :conditions => "rating > 1"
end

class Friendship < ActiveRecord::Base
  belongs_to :user
end

And everything works fine when I manually add friendships through the
console. And I can do things like:

>> user = User.find(:first)
=> #<User:0x25879f4 @attributes={"id"=>"2", "name"=>"jordan"}>
>> user.all_friends
=> [#<User:0x257f358 @attributes={"rating"=>"1", "id"=>"2",
"user_id"=>"2", "name"=>"bob", "friend_id"=>"4"}>, #<User:0x257f31c
@attributes={"rating"=>"2", "id"=>"1", "user_id"=>"2", "name"=>"adam",
"friend_id"=>"3"}>]
>> user.close_friends
=> [#<User:0x257f31c @attributes={"rating"=>"2", "id"=>"1",
"user_id"=>"2", "name"=>"adam", "friend_id"=>"3"}>]

But now if I try to change the rating, it seems to cause problems:

>> friends = user.all_friends
>> f = friends[0]
=> #<User:0x257f358 @attributes={"rating"=>"1", "id"=>"2",
"user_id"=>"2", "name"=>"bob", "friend_id"=>"4"},
@new_record_before_save=nil, @errors=#<ActiveRecord::Errors:0x2579ee4
@errors={}, @base=#<User:0x257f358 ...>>>
>> f.rating = 2
=> 2
>> f.save
ActiveRecord::StatementInvalid: Mysql::Error: Duplicate entry 'bob'
for key 2: UPDATE users SET `name` = 'bob' WHERE id = 2
[... Errors snipped ...]

So there's a few strange things happening here. First off, it's only
updating the User record, not the Friendship record, which makes
sense, since f is a User, but it doesn't help me save the rating.
Also, the id that it is using is the id of the friendship record that
this friend was gathered 'through' (through in quotes because it's not
using :through, which is what I'd like to do, but then I don't know
how I would get the rating for a friendship), and not the id of the
User, so it's trying to update the wrong User. This causes an error
cause now it's updating some other User with the same name as the User
that we're looking at, and names have to be unique.

So how should I be doing this? Also, have I found a bug in RoR? If so,
should I file it? (I'm capable of that, I'm sure...maybe even capable
of fixing it...who knows...).

Thanks in advance for any thoughts anyone has on the matter, maybe
suggestions about how I can do all of this better?

--
Cheers,
Jordan F.
removed_email_address@domain.invalid
This topic is locked and can not be replied to.