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.saveActiveRecord::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
Apparently Analagous 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?