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
.