Search code examples
ruby-on-railshas-manyselfself-reference

has_many :through association in the Rails tutorial


I don't get something in the last chapter of the Rails tutorial.

So the aim of this chapter to make friendships with other users, and that makes it a self referential association. (users have a relationship with other users)

So with the User model, there is the Friendship model, that acts as a through table.

And in the code, class User

class User < ActiveRecord::Base
  has_many :microposts, dependent: :destroy
  has_many :active_relationships,  class_name:  "Relationship",
                                   foreign_key: "follower_id",
                                   dependent:   :destroy
  has_many :passive_relationships, class_name:  "Relationship",
                                   foreign_key: "followed_id",
                                   dependent:   :destroy
  has_many :following, through: :active_relationships,  source: :followed
  has_many :followers, through: :passive_relationships, source: :follower
  .
  .
  .
end

But I don't get this part:

  has_many :following, through: :active_relationships,  source: :followed
  has_many :followers, through: :passive_relationships, source: :follower

We have to specify in the has_many :through association the table that we are going through (Relationship table). But in the above code there isn't an :active_relationships or :passive_relationships table ,there's only a Relationship class.

The Relationship table:

class Relationship < ActiveRecord::Base
  belongs_to :follower, class_name: "User"
  belongs_to :followed, class_name: "User"
  validates :follower_id, presence: true
  validates :followed_id, presence: true
end

So, my question is, how does that work?

Tnx Tom


Solution

  • You are right you have just Relationship class.

    In rails by default there will be has_namy :relationships then you don't have to specify the class name.

    If you don't follow the rails default rules, then when you will try to with different association name , you have to specify the class name.

    In your example

    has_many :active_relationships,  class_name:  "Relationship",
                                   foreign_key: "follower_id",
                                   dependent:   :destroy
    

    Here you specified to find active relationships from Relationship class.

    The has_many :through refers to an association.

    has_many :following, through: :active_relationships,  source: :followed