Получение через ActiveRecord людей, связывающих двух данного человека - PullRequest
0 голосов
/ 24 июня 2011

У меня есть модель Person с:

has_many :from_relationships, :class_name => "Relationship", :foreign_key => "from_person_id"
has_many :to_relationships, :class_name => "Relationship", :foreign_key => "to_person_id"

и модель Отношений с:

belongs_to :from_person, :class_name => "Person"
belongs_to :to_person, :class_name => "Person"

Учитывая человека p1, я хочу реализовать метод экземпляра p1.people_connecting_to (p2), который возвращает всех людей, которые косвенно связывают p1 с другим человеком p2.Например, если у меня есть следующие отношения:

  • p1 => p3 => p2
  • p1 => p4 => p2
  • p1 => p5 =>p6 => p2

Я хочу, чтобы p1.people_connecting_to (p2) вернул [p3, p4].Можно ли достичь в одном запросе SQL через ActiveRecord?

Спасибо:)

РЕДАКТИРОВАТЬ :

Спасибо Эд, ваш ответ приводит меня кследующее решение.Я добавил:

has_many :to_relations, :source => :to_person, :through => :from_relationships
has_many :from_relations, :source => :from_person, :through => :to_relationships

и реализовал people_connecting_to так:

def people_connecting_to(other_person)
  to_relations.joins(:from_relationships).where(:"from_relationships_people.to_person_id" => other_person.id)
end

1 Ответ

0 голосов
/ 24 июня 2011

Вы смотрите на довольно сложный алгоритм .Выполните поиск для в ширину и в глубину и найдите идеи о том, как реализовать рекурсивный метод в вашей модели Person для этого.

Одно общее предложение: настройте личные связи в вашей модели Person, например:

  has_many :from_relations, :source => :from_person, :through => :from_relationships
  has_many :to_relations, :source => :to_person, :through => :to_relationships

Затем вы можете получить набор отношений с @ person.from_relations и @ person.to_relations.

В зависимости от потребностей вашего приложения, вы можете еще больше упростить вещи, имея дело с направлением в вашей модели отношений, например:

Модель человека:

  has_many :relationships
  has_many :relations, :through => :relationships

Модель отношений

  belongs_to :person
  belongs_to :relation, :class_name => "Person"

При более простых ассоциациях метод экземпляра в вашей модели Person, позволяющий определить, связаны ли два человека, будет выглядеть примерно так:

def related_to?(target)
  if self == target
    return true
  elsif self.relations.empty?
    return false
  else
    return self.relations.each {|relation| relation.related_to?(target)}
  end
end

Обратите внимание, что используется рекурсия.Кроме того, я не работал над алгоритмом, чтобы убедиться, что нет потенциала для бесконечных циклов из-за циклических ассоциаций (Джо -> Боб -> Джо -> Боб).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...