2010-05-27 21 views
4

Prendre la asciicast Bates Ryan comme exemple: http://asciicasts.com/episodes/163-self-referential-associationassociations d'auto-référentiels Bidirectionnel

Il se termine par deux associations d'utilisateurs

  • : amis
  • : inverse_friends

Étant donné que un utilisateur ne se soucierait pas qui a initié l'amitié, vous voudriez une association d'utilisateur qui était simplement

  • : amis

que des deux relations consistaient. i.e Les relations déclenchées par l'utilisateur et les relations initiées par l'ami de l'utilisateur. Alors, comment pouvez-vous réaliser cette association autoréférentielle bidirectionnelle?

MISE À JOUR - Josh Susser a un post sur ce ici: http://blog.hasmanythrough.com/2006/4/21/self-referential-through

Cependant, il parle encore has_many: sources et has_many: éviers, alors qu'en réalité il devrait y avoir un has_many: nœuds qui inclut à la fois les sources et la puits

Répondre

8

Voir si cela fonctionne pour vous

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 

est donné un schéma de la table de base de données de

users 
    - id 
    - first_name 
    - etc... 

friendships 
    - id 
    - person_id 
    - friend_id 
+0

Merci! Juste comme une mise à jour. J'ai utilisé la méthode que vous avez décrite ici et cela a bien fonctionné. –