Hello all. I am trying to create a self-referential has_many :through. I used the following site as a guide http://blog.hasmanythrough.com/articles/2006/04/21/self-referential-through but it still doesn''t appear to be working. I have two models. Person and Relationship. A person has many contacts (Which is another person) through relationships class Person < ActiveRecord::Base has_many :relationship has_many :contacts, :through => :relationship end end class Relationship < ActiveRecord::Base belongs_to :person, :foreign_key => "person_id" belongs_to :contact, :foreign_key => "contact_id", :class_name => "Person" end If I use the code as above then while the relationships appear in the view the only "Contact" that appears is the Person I am currently looking at (So the Person "Person A" lists "Person A" as a contact). If, on the other hand I do the following: class Person < ActiveRecord::Base has_many :relationship has_many :contacts, :through => :relationship end end class Relationship < ActiveRecord::Base belongs_to :person, :foreign_key => "person_id" belongs_to :contact, :foreign_key => "contact_id" end class Contact < ActiveRecord::Base set_table_name ''people'' end It works fine. It appears that setting the :contact to :class_name => "Person" screws up the relationship. I would rather avoid defining a separate "Contact" class and use self-referential but I cannot seem to do it. Can anyone offer some advice? Thanks RJ -- Posted via http://www.ruby-forum.com/.
I was recently working on this exact same issue, and finally found another blog with a more descriptive solution (don''t recall where though). Here''s what I eventually came up with after reading that blog.. class User < ActiveRecord::Base has_many :users_as_buddies, :foreign_key => "buddy_id", :class_name => "BuddyList" has_many :users_as_friends, :foreign_key => "friend_id", :class_name => "BuddyList" has_many :buddies, :through => :users_as_friends has_many :friends, :through => :users_as_buddies end class BuddyList < ActiveRecord::Base belongs_to :friend, :foreign_key => "friend_id", :class_name => "User" belongs_to :buddy, :foreign_key => "buddy_id", :class_name => "User" end buddies; people I''ve added to my buddy list. friends; people who''ve added ME to THEIR buddy list. buddies != friends What happens is, if User A adds User B to their buddy list, User B adds User C to their own buddy list, and User C adds both User''s A and B to thier own buddy list, then... @usera.buddies => UserB @usera.friends => UserC @userb.buddies => UserC @userb.friends => [UserA, UserC] @userc.buddies => [UserA, UserB] @userc.friends => UserB Note that some people would want it so that if User A adds User B to his buddy list, then User A is automatically on User B''s buddy list. I''m sure this could be done programatically by adding a mirror image row to the buddy_lists table every time a buddy list entry is created, but I''m not sure how to do that strictly through the model relationships. However, I didn''t want that "feature" for myself, so I wasn''t worried about it. YMMV. RurouniJones wrote:> Hello all. > > I am trying to create a self-referential has_many :through. I used the > following site as a guide > http://blog.hasmanythrough.com/articles/2006/04/21/self-referential-through > but it still doesn''t appear to be working. I have two models. Person and > Relationship. A person has many contacts (Which is another person) > through relationships > > class Person < ActiveRecord::Base > has_many :relationship > has_many :contacts, :through => :relationship end > end > > class Relationship < ActiveRecord::Base > belongs_to :person, :foreign_key => "person_id" > belongs_to :contact, :foreign_key => "contact_id", :class_name => > "Person" > end > > If I use the code as above then while the relationships appear in the > view the only "Contact" that appears is the Person I am currently > looking at (So the Person "Person A" lists "Person A" as a contact). > > If, on the other hand I do the following: > > class Person < ActiveRecord::Base > has_many :relationship > has_many :contacts, :through => :relationship end > end > > class Relationship < ActiveRecord::Base > belongs_to :person, :foreign_key => "person_id" > belongs_to :contact, :foreign_key => "contact_id" > end > > class Contact < ActiveRecord::Base > set_table_name ''people'' > end > > It works fine. It appears that setting the :contact to :class_name => > "Person" screws up the relationship. I would rather avoid defining a > separate "Contact" class and use self-referential but I cannot seem to > do it. > > Can anyone offer some advice? > > Thanks > > RJ > >
RurouniJones wrote:> I am trying to create a self-referential has_many :through. I used the > following site as a guide > http://blog.hasmanythrough.com/articles/2006/04/21/self-referential-through > but it still doesn''t appear to be working. I have two models. Person and > Relationship. A person has many contacts (Which is another person) > through relationships > > class Person < ActiveRecord::Base > has_many :relationship > has_many :contacts, :through => :relationship end > end > > class Relationship < ActiveRecord::Base > belongs_to :person, :foreign_key => "person_id" > belongs_to :contact, :foreign_key => "contact_id", :class_name => > "Person" > end > > If I use the code as above then while the relationships appear in the > view the only "Contact" that appears is the Person I am currently > looking at (So the Person "Person A" lists "Person A" as a contact). > > If, on the other hand I do the following: > > class Person < ActiveRecord::Base > has_many :relationship > has_many :contacts, :through => :relationship end > end > > class Relationship < ActiveRecord::Base > belongs_to :person, :foreign_key => "person_id" > belongs_to :contact, :foreign_key => "contact_id" > end > > class Contact < ActiveRecord::Base > set_table_name ''people'' > end > > It works fine. It appears that setting the :contact to :class_name => > "Person" screws up the relationship. I would rather avoid defining a > separate "Contact" class and use self-referential but I cannot seem to > do it. > > Can anyone offer some advice?Take another look at my article and you''ll see you left out a couple things. One, you are using teh singular :relationship for the has_many association, and you should be using the plural :relationships. But more importantly, you don''t have a :class_name option on the :contacts association. You are also missing the :people association to go the other direction in the mapping. And you seem to have a spurious "end" in your Person :contacts declaration. Not sure if those are email artifiacts or in your real code, so who knows. You''re pretty close though. Just take another pass to make it work like described in the article and it should be fine. -- Josh Susser http://blog.hasmanythrough.com -- Posted via http://www.ruby-forum.com/.