2010-05-27 53 views
4

以Ryan Bates的asciicast为例:朋友 双向自我指涉协会

  • :inverse_friends
  • 鉴于 http://asciicasts.com/episodes/163-self-referential-association

    他与用户的两个协会

    • 结束用户不会在意谁激起了友谊,你会想要一个用户协会,只是

      • :朋友

      是由两个关系。即由用户发起的关系以及由用户的朋友发起的关系。

      那么你怎么能实现这种双向的自我指涉关联?

      更新 - 乔希Susser有一个关于这个帖子在这里: http://blog.hasmanythrough.com/2006/4/21/self-referential-through

      然而,仍有约的has_many谈判:来源和的has_many:汇时候,确实应该有一个的has_many:同时包含源和节点汇。

    回答

    8

    看看这是否适合你?

    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 
    

    这是送给

    users 
        - id 
        - first_name 
        - etc... 
    
    friendships 
        - id 
        - person_id 
        - friend_id 
    
    +0

    感谢的数据库表模式!就像更新一样。我使用了你在这里描述的方法,它运行良好。 – 2010-07-21 12:05:29