Has_many: Through: Source:

Here’s a very simple model of Employee and her/his family

class Employee < ActiveRecord::Base
  has_many: :families
end

class Family < ActiveRecord::Base
  belongs_to: :employee
end

Now if I wanted to add a Company to which employees belong, so that I can invite all the family members of a company’s employees

class Employee < ActiveRecord::Base
  has_many: :families
  belongs_to: :company
end

class Family < ActiveRecord::Base
  belongs_to: :student
end

class Company < ActiveRecord::Base
  has_many: :employees
  has_many: :employee_families, :through => :employees, :source => :families
end

:employee_families is a name I would like to use in Company to refer to all the family members of a company’s employees. Employee class doesn’t have any :employee_families association on it, so I need to define it inside Company using :source => :famlies.

This provides context to :families. For example, an employee has families: @employee.families. If I wanted to get all the family members of a company’s employees, i can do something like this: @company.employees.families. This is same as @company.employee_families.

Another example. This time it’s a self-referential association. Let’s say I want to create a Twitter clone. A User follows another User.

class Relationship
  belongs_to: :followed, class_name: :User
  belongs_to: :follower, class_name: :User
end

class User
  has_many: :relationships, foreign_key: :followed_id
  has_many: :followed_users, through: :relationships, source: :followed

  has_many: :reverse_relationships, foreign_key: :follower_id
  has_many: :follower_users, through: :relationships, source: :follower
end

In this case, depending on what I specify as source: it can mean entirely different things, since User can play two different roles: followed and follower.