Taking Ryan Bates' asciicast as an example: http://asciicasts.com/episodes/163-self-referential-association
He ends with two associations of User
- :friends
- :inverse_friends
Given that a user would not care who instigated the friendship, you would want a User association that was simply
- :friends
that consisted of both relationships. i.e Relationships instigated by the user and relationships instigated by the user's friend.
So how can you achieve this bidirectional self-referential association?
UPDATE - Josh Susser has a post about this here: http://blog.hasmanythrough.com/2006/4/21/self-referential-through
However, it still talks about has_many :sources and has_many :sinks when really there should be a has_many :nodes that includes both the sources and the sinks.
see if this works for you?
class User < ActiveRecord::Base
has_many :friendships, :foreign_key => "person_id", :class_name => "Friendship"
has_many :friends, :through => :friendships
def befriend(user)
# TODO: put in check that association does not exist
self.friends << user
user.friends << self
end
end
class Friendship < ActiveRecord::Base
belongs_to :person, :foreign_key => "person_id", :class_name => "User"
belongs_to :friend, :foreign_key => "friend_id", :class_name => "User"
end
# Usage
jack = User.find_by_first_name("Jack")
jill = User.find_by_first_name("Jill")
jack.befriend(jill)
jack.friends.each do |friend|
puts friend.first_name
end
# => Jill
jill.friends.each do |friend|
puts friend.first_name
end
# => Jack
this is given a database table schema of
users
- id
- first_name
- etc...
friendships
- id
- person_id
- friend_id
来源:https://stackoverflow.com/questions/2923692/bidirectional-self-referential-associations