A User can have many:
- followers in its capacity as followee
- followees in its capacity as follower.
Here's how the code for user.rb might look:
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
Here's how the code for 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
The most important things to note are probably the terms :follower_follows
and :followee_follows
in user.rb. To use a run of the mill (non-looped) association as an example, a Team may have many :players
through :contracts
. This is no different for a Player, who may have many :teams
through :contracts
as well (over the course of such Player's career).
But in this case, where only one named model exists (i.e. a User), naming the through: relationship identically (e.g. through: :follow
) would result in a naming collision for different use cases of (or access points into) the join table. :follower_follows
and :followee_follows
were created to avoid such a naming collision.
Now, a User can have many :followers
through :follower_follows
and many :followees
through :followee_follows
:
- To determine a User’s :followees (upon an
@user.followees
call to the database), Rails may now look at each instance of class_name: “Follow” where such User is the the follower (i.e. foreign_key: :follower_id
) through: such User’s :followee_follows.
- To determine a User’s :followers (upon an
@user.followers
call to the database), Rails may now look at each instance of class_name: “Follow” where such User is the the followee (i.e. foreign_key: :followee_id
) through: such User’s :follower_follows.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…