DEV Community

Cover image for Ruby & Active Record Associations
Megan Moulos
Megan Moulos

Posted on

Ruby & Active Record Associations

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

belongs to association

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:

has many through

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:

polymorphic

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.

Top comments (0)