Megan Moulos
Posted on October 3, 2022
In this guide you will learn:
- How to declare associations between models using Active Record
- How to understand the different types of associations available with Active Record
- How to use the methods automatically added to your models after creating these associations
Using associations with Active Record is very powerful and an important part of using Ruby with databases. An association is a connection between two Active Record models. These associations provide built-in methods to make your databases easier to work with. This walkthrough assumes that you already understand how to create migrations and models.
There are 6 types of associations:
belongs_to
has_one
has_many
has_many :through
has_one :through
has_and_belongs_to_many
To figure out which type of association that fits your needs, it is helpful to create an ** Entity Relationship Diagram (ERD)**. There are helpful tools online to create your own ERD quickly and easily, but you can also use pen and paper!
For this walkthrough, we will use dbdiagram.io.
belongs_to, has_many
The belongs_to
association sets up a connection between two models, where the instance of one model "belongs to" the second model. In this example we have one author who has written many books. In this case, each book belongs_to
an author. This association is made through the foreign key.
Note: From Flatiron School docs - "Foreign keys are columns that refer to the primary key of another table. Conventionally, foreign keys in Active Record are comprised of the name of the model you're referencing, and _id. So for example if the foreign key was for a posts table it would be post_id." Read more about foreign keys at The Odin Project.
Here is the corresponding code:
class Book < ActiveRecord::Base
belongs_to :author
end
Note that the belongs_to
association must use the singular term ("author"). From the official docs: "This is because Rails automatically infers the class name from the association name. If the association name is wrongly pluralized, then the inferred class will be wrongly pluralized too."
The other side of the coin for this particular example, the author's has_many
relationship, would look like this:
class Author < ActiveRecord::Base
has_many :books
end
belongs_to, has_one
If we changed our example above so that each author only wrote a single book, we could use the has_one
association:
class Author < ActiveRecord::Base
has_one :book
end
Notice that book
is singular. This may seem intuitive, but it is very important to note when to use singular or plural cases when writing your associations. The Book model would remain the same in this case, reading belongs_to: author
in the singular.
has_many, through:
This association is often used to set up a many-to-many connection with another model. The declaring model can be matched with instances of another model through a third, connecting model. For example, imagine a hospital with doctors that see many patients through the patients' appointments. The diagram would look like this:
Each doctor has many patients through the appointments table. The patient also has many doctors through the appointments table. Here is the corresponding association code:
class Doctor < ActiveRecord::Base
has_many :appointments
has_many :patients, through: :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :doctor
belongs_to :appointment
end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :doctors, through: :appointments
end
Then new join models are automatically created for the newly associated objects.
has_one, through:
The has_one, through:
association is similar to the has_many, through:
association because they both create join models automatically. The difference is in the syntax, and that there is a one to many relationship. In our example above, imagine a patient only had one doctor, through the patient's appointments:
class Doctor < ActiveRecord::Base
has_many :appointments
has_many :patients, through: :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :doctor
belongs_to :appointment
end
class Patient < ActiveRecord::Base
has_many :appointments
has_one :doctor, through: :appointments
end
has_and_belongs_to_many
This association is rarely used, and there is a blog post titled "Why You Don’t Need Has_and_belongs_to_many Relationships explaining why. From the Rails docs:
The simplest rule of thumb is that you should set up a has_many :through relationship if you need to work with the relationship model as an independent entity. If you don't need to do anything with the relationship model, it may be simpler to set up a has_and_belongs_to_many relationship (though you'll need to remember to create the joining table in the database).
Bonus: Polymorphic Association
Polymorphic association allows us to connect a model to multiple other models on a single association. Look at this table provided by the Rails Active Record documentation:
A polymorphic belongs_to
declaration sets up an interface that any other model can use. For example, from an instance of an Employee model, a collection of pictures can be retrieved using @employee.pictures. You could also retrieve @product.pictures by the same logic.
Find more information, as well as helpful tips and tricks, in the official documentation here.
Posted on October 3, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.