我有一个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.people_connecting_to(p2)返回[p3,p4]。是否可以通过ActiveRecord在单个SQL请求中实现?
谢谢:)
修改:
感谢Ed,您的回答引导我找到以下解决方案。我添加了:
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
答案 0 :(得分:0)
你正在寻找一个相当复杂的algorithm。搜索breadth-first和depth-first搜索以获取有关如何在Person模型中实现递归方法的建议。
一个一般性建议:在Person模型中设置Person-to-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
注意它使用递归。此外,我没有通过算法来确保由于循环关联而无法实现无限循环(Joe - > Bob - > Joe - > Bob)。