Jordan Frank
2006-Mar-25 05:37 UTC
[Rails] Self-Referential Many-To-Many relationships where the relationship itself has data.
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 Frank
jordan.w.frank@gmail.com
Seemingly Similar Threads
- Self-referential has_many :through relationship
- Self-referential MtoM implementation
- Adding objects to a :through association
- How to access attribute in a self-referential many-to-many relationship
- Any progress on undirected self-referential many to many relationships?
