多对多的自我加入铁轨?

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

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

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

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

用户可以有很多:

  • 追随者以跟随者的身份
  • 跟随者作为追随者。

以下是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 

以下是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 

需要注意的最重要的事情可能是以下术语:follower_follows:followee_follows中的followee_follows。 作为一个例子,使用磨坊(非循环)协会的运行, 团队可能有很多: players通过:contracts 。 这对于一个可能有很多人的球员来说也没有什么不同:teams通过:contracts (在球员职业生涯中)。

但在这种情况下,只存在一个命名模型(即用户 ),相同地命名through:relationship(例如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 ),通过:这样的用户 :follower_follows。