Bidirectional self referential associations

这一生的挚爱 提交于 2019-11-30 15:48:54

问题


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.


回答1:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!