Relational databases have tables related to each other, and their relationship is established with primary and foreign keys. In Rails, the Active Record associations allow you to define relationships between models. Associations indicate how your models relate to each other. When you set up an association between models, Rails migration defines the Primary Key and Foreign Key relationships, ensuring the consistency and integrity of the database.
Rails supports six types of associations.
- belongs_to
- has_one
- has_many
- has_many :through
- has_one :through
- has_and_belongs_to_many
belongs_to Association
Consider a case of Book and Author models, where each book can be assigned to exactly one author. A belongs_to association reflects the relationship between the two.
Generate the models with the following commands −
rails generate model Author name:string rails generate model Book title:string author:references
Rails generates the Book model with a foreign key column (author_id) and sets up the belongs_to association.
classBook<ApplicationRecord belongs_to :authorend
The database server creates the tables books and authors with the relationship expressed by primary and foreign keys.

The belongs_to association means that this model’s table contains a column which represents a reference to another table. Use belongs_to in combination with a has_one or has_many to set up one-directional or bi-directional relationship.
has_one Association
A has_one association is useful when one other model has a reference to this model. That model can be fetched through this association. For example, if each supplier in your application has only one account.
Open the command prompt and use the following commands to generate the models −
rails generate model Supplier name:string rails generate model Account account_number:string supplier:references
Edit the supplier.rb script and define the haas_one association with account model.
classSupplier<ApplicationRecord has_one :accountend
In the underlying database, the relationship between suppliers and accounts tables is reflected by the following figure −

The has_one association creates a one-to-one match with another model. says that the other class contains the foreign key. This relation can be bi-directional when used in combination with belongs_to on the other model.
has_many Association
A has_many association is similar to has_one, but indicates a one-to-many relationship with another model. This association indicates that each instance of the model has zero or more instances of another model.
This is how the has_many association is established between Author and multiple instances of Book model.
classAuthor<ApplicationRecord has_many :booksend
The equivalent relationship diagram is as follows −

The has_many establishes a one-to-many relationship between models, allowing each instance of the declaring model (Author) to have multiple instances of the associated model (Book).
Unlike a has_one and belongs_to association, the name of the other model is pluralized when declaring a has_many association.
has_many :through Association
A has_many :through association is often used to set up a many-to-many relationship with another model through an intermediate model. This association indicates that the declaring model can be matched with zero or more instances of another model by proceeding through a third model.
Consider a situation where a Doctor can have multiple Patients and a Patient can have multiple Doctors through Appointments, you can use a has_many :through association.
Generate the following models with these commands −
rails generate model Doctor name:string specialization:string rails generate model Patient name:string age:integer rails generate model Appointment doctor:references patient:references appointment_date:datetime
Now, create the associations. Edit the doctor.db script in app/models directory.
classDoctor<ApplicationRecord has_many :appointments has_many :patients, through::appointmentsend
The patient model also should have the has_many association with appointments and doctors (note the use of plurals) models
classPatient<ApplicationRecord has_many :appointments has_many :doctors, through::appointmentsend
Lastly associate the Appointment model with Doctor and Patient models with belongs_to association.
classAppointment<ApplicationRecord belongs_to :doctor belongs_to :patientend
has_one :through Association
A has_one :through association sets up a one-to-one relationship with another model through an intermediary model. This association indicates that the declaring model can be matched with one instance of another model by proceeding through a third model.
- Employee, Office, and Company
- An Employee works in an Office.
- Each Office belongs to a Company.
- An Employee belongs to a Company through their Office.
If the models are set up as follows −
rails generate model Company name:string rails generate model Office location:string company:references rails generate model Employee name:string office:references
The Employee model is associated with Company with has_one:though type, and there’s a belongs_to association between Employee and Office models.
classEmployee<ApplicationRecord belongs_to :office has_one :company, through::officeend
has_and_belongs_to_many Association
A has_and_belongs_to_many association creates a direct many-to-many relationship with another model, with no intervening model. This association indicates that each instance of the declaring model refers to zero or more instances of another model.
For example, consider an application with Assembly and Part models, where each assembly can contain many parts, and each part can be used in many assemblies.
Generate the models −
rails generate model Assembly name:string rails generate model Part name:string
Establish the associations −
classAssembly<ApplicationRecord has_and_belongs_to_many :partsendclassPart<ApplicationRecord has_and_belongs_to_many :assembliesend
The has_and_belongs_to_many association creates a direct many-to-many association. Even though a has_and_belongs_to_many does not require an intervening model, it does require a separate table to establish the many-to-many relationship between the two models involved.
Leave a Reply