4

Ryan Bates の asciicast を例にとると: http://asciicasts.com/episodes/163-self-referential-association

彼は User の 2 つの関連付けで終了します。

  • :友達
  • :inverse_friends

ユーザーが誰が友情を開始したかを気にしないことを考えると、単純な User アソシエーションが必要になります。

  • :友達

両方の関係で構成されていました。すなわち、ユーザーによって扇動された関係と、ユーザーの友人によって扇動された関係です。

では、この双方向の自己参照関連をどのように実現できるのでしょうか?

更新 - Josh Susser がこれについて投稿しています: http://blog.hasmanythrough.com/2006/4/21/self-referential-through

ただし、実際にはソースとシンクの両方を含む has_many :nodes が必要な場合でも、 has_many :sources と has_many :sinks について説明しています。

4

1 に答える 1

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
于 2010-05-27T19:21:01.607 に答える