All Associations in rails explained in a single app

This article explains all types of associations rails supports, explaining it in a single real-time application, which would give more vivid picture.

Say, we have college-placement software, having following models:

1. College
2. Student
3. Company
4. Application
5. Profile
6. ProfileHistory

belongs_to

Student belongs to a college. We set-up relation between Student and College as follows:

class Student < ApplicationRecord
  belongs_to :college
end

Adding a reference key college_id to Student table.

rails g migration addColToStudents

class AddColToStudent < ActiveRecord::Migration
  def change
    add_column :students, :college_id, :integer
  end
end

Note: rake db:migrate goes without saying for all migrations here.
created_at and updated_at are having dummy values.

Now the below relation is established.

@student.college  = College id: 1, name: "EP College of Technology", created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530

has_many

There are many students in a college, or in other words, college has many students. Relation between a college and student can be established as below:

class College < ApplicationRecord
  has_many :students
end

Adding a reference key college_id to Student table.

rails g migration addColToStudent

class AddColToStudent < ActiveRecord::Migration
  def change
    add_column :students, :college_id, :integer
  end
end

Now the below relation is established.

@college.students  = [Student id: 1, name: "Tim John", created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530, Student id: 2, name: "Lucy", created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530, .....]

has_one

Here, for each student there is a profile, in other words, each student has one profile associated with it.

class Student < ApplicationRecord
  has_one :profile
end

class Profile < ApplicationRecord
  belongs_to :student
end

Adding a reference key student_id to Profile table.

rails g migration addColToProfiles

class AddColToProfiles < ActiveRecord::Migration
  def change
    add_column :profiles, :student_id, :integer
  end
end
@student.profile = Profile id: 1, name: "All-star", created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530

@profile.student = Student id: 1, name: "Tim John", created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530

has_many :through

has_many through being one of the most important association to be understood. Now, there are many students applying for many companies and many companies are receiving applications from many students. We have many to many relationship here.

class Student < ApplicationRecord
  has_many :applications
  has_many :companies, through: applications
end

class Company < ApplicationRecord
  has_many :applications
  has_many :students, through: applications
end

class Application < ApplicationRecord
  belongs_to :student
  belongs_to :company
end

Create a table Application or adding a reference keys student_id, company_id to Application table.

rails g migration addColToApplications

class AddColToApplications < ActiveRecord::Migration
  def change
    add_column :applications, :student_id, :integer
    add_column :applications, :company_id, :integer
  end
end

These are the methods accessible for each student and company object.

@student.applications = [Application id: 1, company_id: 1, student_id: 2, created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530, Application id: 2, company_id: 2, student_id: 3, created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530, .....]

@student.companies = [Company id: 1, name: "Apple", created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530, Company id: 2, name: "Microsoft", created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530, .....]

@company.applications = [Application id: 1, company_id: 1, student_id: 2, created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530, Application id: 2, company_id: 2, student_id: 3, created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530, .....]

@company.students = [Student id: 1, name: "Tim John", created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530, Student id: 2, name: "Lucy", created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530, .....]

has_one :through

Here, a student has a profile and profile history. The only difference between has_many :through having one to one relationship rather than one to many.

class Student < ApplicationRecord
  has_one :profile_history
  has_one :profile, through: profile_history
end

class Profile < ApplicationRecord
  has_one :profile_history
  has_one :student, through: profile_history
end

class ProfileHistory < ApplicationRecord
  belongs_to :student
  belongs_to :profile
end

Create a table Application or adding a reference keys student_id, profile_id to Application table.

rails g migration addColToProfileHistory

class AddColToProfileHistory < ActiveRecord::Migration
  def change
    add_column :profile_histories, :student_id, :integer
    add_column :profile_histories, :profile_id, :integer
  end
end

These are the methods accessible for each student and profile object.

@student.profile_history = ProfileHistory id: 1, profile_id: 1, student_id: 2, created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530

@student.profile = Profile id: 1, name: "All-star", created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530

@profile.profile_history = ProfileHistory id: 1, profile_id: 1, student_id: 2, created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530

@profile.student = Student id: 1, name: "Tim John", created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530

has_and_belongs_to_many

This association is rarely used, as the same relation can be done using has_many :through in a more effective way.
We take same example for many students applying for many companies and many companies receiving applications from many students.

class Student < ApplicationRecord
  has_and_belongs_to_many :companies
end

class Company < ApplicationRecord
  has_and_belongs_to_many :students
end

Create a table Application or adding a reference keys student_id, company_id to Application table.

rails g migration addColToApplications

class AddColToApplications < ActiveRecord::Migration
  def change
    add_column :applications, :student_id, :integer
    add_column :applications, :company_id, :integer
  end
end

These are the methods accessible for each student and company object.

@student.companies = [Company id: 1, name: "Apple", created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530, Company id: 2, name: "Microsoft", created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530, .....]

@company.students = [Student id: 1, name: "Tim John",  created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530, Student id: 2, name: "Lucy", created_at: 2017-09-23 22:28:19 +0530, updated_at: 2017-09-23 22:28:19 +0530, .....]

2 Responses to “All Associations in rails explained in a single app

  • I think thuat what you composed was very logical. But, what about this?
    suppose you were too create a awesome post title?

    I ain’t suggesting your content isn’t good, however
    suppose you added a hedline to possibly grab people’s attention? I mean All
    Associations in rails explained iin a single app – TechEnthu is a little vanilla.

    You could lok at Yahoo’s hkme page and see how they create pot eadlines to get people to open the links.
    You might add a related video or a related picture or two tto get readers interested about what you’ve got
    tto say. In my opinion, it could make your websige a little livelier.

    • adminsrini
      7 years ago

      Hi Greece Ferry,

      Thank you so much for your feedback. Will make it more livelier. Thank you for making us better 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *