Rails相同类多对多人际关系关联双向查询实现咨询
实现方案
第一步:配置Relationship模型
先完成中间表的基础关联和枚举定义:
class Relationship < ApplicationRecord # 定义connection枚举值,可根据业务扩展 enum connection: { colleagues: "colleagues", friends: "friends", siblings: "siblings" } belongs_to :person_a, class_name: "Person" belongs_to :person_b, class_name: "Person" end
第二步:配置Person模型,实现双向关联
你之前用has_and_belongs_to_many达不到目标的核心原因是中间表有两个外键指向同一张表,默认的HABTM只会匹配单个外键方向,需要手动合并两个方向的查询结果:
class Person < ApplicationRecord # 定义两个方向的中间表关联 has_many :active_relationships, class_name: "Relationship", foreign_key: "person_a_id", dependent: :destroy has_many :passive_relationships, class_name: "Relationship", foreign_key: "person_b_id", dependent: :destroy # 需求1:双向查询所有关联的person def people # 合并当前人作为person_a关联的person_b、作为person_b关联的person_a,自动去重 Person.where(id: active_relationships.select(:person_b_id)) .or(Person.where(id: passive_relationships.select(:person_a_id))) .distinct end # 需求2:双向查询所有好友(connection为friends的关联) def friends active_friend_ids = active_relationships.friends.select(:person_b_id) passive_friend_ids = passive_relationships.friends.select(:person_a_id) Person.where(id: active_friend_ids) .or(Person.where(id: passive_friend_ids)) .distinct end end
关联记录仅需创建1条即可,无需同时创建
person_a=对方、person_b=自己的反向重复记录,上面的查询逻辑会自动覆盖两个方向的匹配。
效果验证
- 创建测试数据:
p1 = Person.create(name: "张三") p2 = Person.create(name: "李四") Relationship.create(person_a: p1, person_b: p2, connection: :friends)
- 验证双向查询:
p1.people返回p2,p2.people返回p1p1.friends返回p2,p2.friends返回p1
内容的提问来源于stack exchange,提问作者Bexultan Myrzatay
相关产品推荐
相关产品推荐

