多对多的自我加入铁轨?

jbm*_*rom 4 activerecord ruby-on-rails

Rails文档提供了一个很好的解释,说明如何处理只需要has_many-belongs_to关系的自连接.在该示例中,员工(作为经理)可以拥有许多员工(每个员工作为下属).

但是,你如何处理has_many-has_many自联接(我听说这被称为双向循环关联)?

例如,您如何处理员工以管理者身份拥有许多下属并且还有许多管理人员作为下属的情况?

或者,换句话说,用户可以关注许多用户并被许多用户跟踪?

jbm*_*rom 17

一个用户可以有很多:

  • 追随者以跟随者的身份
  • 以跟随者的身份跟进.

以下是user.rb代码的外观:

class User < ActiveRecord::Base
  # follower_follows "names" the Follow join table for accessing through the follower association
  has_many :follower_follows, foreign_key: :followee_id, class_name: "Follow" 
  # source: :follower matches with the belong_to :follower identification in the Follow model 
  has_many :followers, through: :follower_follows, source: :follower

  # followee_follows "names" the Follow join table for accessing through the followee association
  has_many :followee_follows, foreign_key: :follower_id, class_name: "Follow"    
  # source: :followee matches with the belong_to :followee identification in the Follow model   
  has_many :followees, through: :followee_follows, source: :followee
end
Run Code Online (Sandbox Code Playgroud)

以下是follow.rb的代码:

class Follow < ActiveRecord::Base
  belongs_to :follower, foreign_key: "follower_id", class_name: "User"
  belongs_to :followee, foreign_key: "followee_id", class_name: "User"
end
Run Code Online (Sandbox Code Playgroud)

需要注意的最重要的事情可能是条款:follower_follows:followee_followsuser.rb. 例如,要使用mill(非循环)关联的运行,团队可能有很多:playersthrough :contracts.这是一个没有什么不同球员,谁可能有很多:teams通过:contracts,以及(在这样的过程中球员的职业生涯).

但在这种情况下,只存在一个命名模型(即用户),以相同方式命名贯穿:关系(例如through: :follow)会导致连接表的不同用例(或访问点)的命名冲突.:follower_follows:followee_follows创建以避免这种命名冲突.

现在,用户可以:followers通过以下方式获得:follower_follows许多:followees通过:followee_follows:

  • 要确定用户:followees(在@user.followees调用数据库时),Rails现在可以查看class_name的每个实例:"Follow",其中User是跟随者(即foreign_key: :follower_id)通过:这样的用户:followee_follows.
  • 为了确定用户:关注者(在@user.followers调用数据库时),Rails现在可以查看class_name的每个实例:"Follow",其中User是followee(即foreign_key: :followee_id):这样的User 's:follower_follows.