Loading...
New webinar: "The Remote Job Search: My Microverse Journey" with graduate Paul Rail
Watch Now

Topics

Rapid technological advancements over the past years have led to more complex interactions and associations between data models. That's why, in this article we’ll discuss Associations and Class Names in Rails, and how the relationship works together to help you achieve your desired results.

We will cover the four categories of Associations in Rails, then dive into Class Names.

Association in Ruby on Rails

In Ruby on Rails, Active Record provides an interface between tables in a relational database. In MVC, Active Record is the M the model. The Model communicates with the database, sends information to the controller, and is a SQL table. Association in Rails defines the relationship between models. It is also the connection between two Active Record models.

To figure out the relationship between models, we have to determine the types of relationship. Whether it; belongs_to, has_many, has_one, has_one:through, has_and_belongs_to_many.

Let’s divide association into categories:

  1. One to One
  2. One to Many
  3. Many to Many
  4. Polymorphic

To better understand these categories, I've created a video tutorial walking through these steps, located at the bottom of the article.

One to One

This relationship has to do with one instance of another model. One of the models in this relationship will have a has_one method invocation and another will have a belongs_to.

For example; every student in a Nigerian university is supposed to have a matric number (a Student Identification Number). To create a model for this, we need to run rails generate model Student and rails generate model Matric_no.

When the migration is generated, this is how the model will look before an association is added:

{% code-block language="js" %}
class Student < ApplicationRecord
end
class Matric_no < ApplicationRecord
end
{% code-block-end %}

An example of how the model will look like when an association is added:

{% code-block language="js" %}
class Student < ApplicationRecord      
  has_one :matric_no                    
end
class Matric_no < ApplicationRecord      
  belongs_to :student                  
end
{% code-block-end %}

Also, belongs_to is used to show a reference to another one and describes which model contains a foreign key. Additionally, belongs_to associations must use the singular term.

Student and rails generate model Matric_no

One to Many

This is one of the most common relationships in Rails. One to many means zero or more instances of another model. This relationship includes two models, has_many and belongs_to.

Let’s say we want to create an application where a user can create many posts:

{% code-block language="js" %}
class User < ApplicationRecord      
    has_many :posts                   
end
class Post < ApplicationRecord      
    belongs_to :user
end
{% code-block-end %}

This association indicates that each instance of the user can have zero or more instances of another model and post belongs to only one model. The post model contains one reference to the user model in the form of a foreign key.

Relationship b/w User and Post

Notice that the name of the other model is pluralized when declaring a has_many association.

Many to Many

When two models have a has_many association with each other, it means a many-to-many relationship. For this relationship, we have has_and_belongs_to_many and has_many: through.

Has_and_belongs_to_many Association

A has_and_belongs_to_many association creates a direct many-to-many connection with another model. For this model to work, we need to use a join table.

Join tables are populated with (at least) the primary key and the foreign key of a relationship.

Relationship b/w User and Book

The naming convention of the join table would take the name of both models. It also requires calling has_and _belongs_to_many on both models. 

See example below:

{% code-block language="js" %}
class User < ApplicationRecord      
   has_and_belongs_to_many :posts                
end
class Book < ApplicationRecord      
   has_and_belongs_to_many :users
end
{% code-block-end %}

Notice here that users and books must be pluralized.

Has_many: through Association

Has_many: through association sets up a many-to-many association using another model. It creates direct many-to-many connections with another model. In this association, we need three models to make it work:

{% code-block language="js" %}
class User < ApplicationRecord                  
end
class Book < ApplicationRecord      
end
class BookGroup < ApplicationRecord     
end
{% code-block-end %}

In this many-to-many relationship, a user can have many books, and a book belongs to a different book_group. The book_group here represents the genres of literature. In order to do that, we need to create a new join model. 

In this example, we will use User, Book and Book_group:

{% code-block language="js" %}
class User < ApplicationRecord      
    has_many :book_groups
    has_many :books, through: :book_groups            
end
class BookGroup < ApplicationRecord      
    belongs_to :user 
    belongs_to :book
end
class Book < ApplicationRecord
    has_many :book_groups
    has_many :books, through: :book_groups 
end
{% code-block-end %}

Notice that the Book_group is the join model. So the user has many books and many books through book_groups. The book also has many book_groups and many users to see through book_groups. 

Other uses for the has_many: through Association

The has_many: through association is also useful for setting up “shortcuts” through nested has_many associations. Additionally, this association will enable us to get access to data specific to the relation between user and book_group models. We can have something like user.book.

Polymorphic Association

A polymorphic association is an Active Record association that can connect a model to multiple other models. It is the most advanced association available to us. Polymorphic associations give room to single associations based on the fact that a model can belong to more than one other model. 

For example:

{% code-block language="js" %}
class Review < ApplicationRecord
  belongs_to :reviewable, polymorphic: true
end
class Location < ApplicationRecord
  has_many :reviews, as: :reviewable
end
class Event < ApplicationRecord
  has_many :reviews, as: :reviewable
end
{% code-block-end %}

From the above example, you might have a review model that belongs to either an event model or a location model. Polymorphic belongs_to is for setting up an interface that any other model can use. We can use @location.reviews @event.reviews to retrieve data.

Now, we’ve covered the four categories of Associations and you should better understand how, and when, to use these. Next, we will explore class_names in Ruby on Rails. 

But first, below is the video tutorial I created to go over these associations concepts:


Class_name in Ruby on Rails

Sometimes we find ourselves wondering, “When do I need to specify the class_name in an association?”

We know naming in Rails can be confusing. In Rails, we can have multiple associations in a model. A common use case of class_name in Rails association is when using aliases for our association.

A typical example is saying; a User model has many friends, but we only have the user model. We could create a friend model but that would be duplication of data. So, we say a user has_many friends, then we tell Rails that we don't have a friend model, so use the model specified with class_name.

{% code-block language="js" %}
class Book < ApplicationRecord
  has_many :friends, class_name: 'User'
end
{% code-block-end %}

By default when defining association in Rails you reference the name of the model you are associating with the other. 

For example;

{% code-block language="js" %}
class User < ApplicationRecord
   has_many :names
end
{% code-block-end %}

In the above example,, there has to be a model called ‘Name’. The pluralized title of the Name model is used, as it is expected that a user will have many names and not just one name.

In a situation where we want a user to have nicknames, we wouldn’t want to generate another model, but we don’t have a ‘nickname’ model. So, we give the relationship an alias, then specify the class to associate that alias with.

For example;

{% code-block language="js" %}
Class User
    has_many :nicknames, class_name: ‘Name’.
end
{% code-block-end %}

Above we specified that a user has many nicknames but since we don’t have a nickname model, we then specified the model using the class_name keyword. The above shows some examples for how you can use class names in an association.

Conclusion

In this article we dove into associations and class names in Rails. The good thing about association in Rails is that it allows us to think and determine the relationship, as well as modify it as we want. 

As noted, there are four highlighted categories of association in Rails, which includes; One to One, One to Many, Many to Many, and Polymorphic associations. Class_name allows the naming of a class to be different than what Rails expects. Each association in Ruby on Rails is unique in showing its specialties based on how it is applied. After reading this, you should have a better understanding of how to use associations and class names in Ruby on Rails.

Happy Coding!


Subscribe to our Newsletter

Get Our Insights in Your Inbox

Career advice, the latest coding trends and languages, and insights on how to land a remote job in tech, straight to your inbox.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
We use own and third party cookies to; provide essential functionality, analyze website usages, personalize content, improve website security, support third-party integrations and/or for marketing and advertising purposes.

By using our website, you consent to the use of these cookies as described above. You can get more information, or learn how to change the settings, in our Cookies Policy. However, please note that disabling certain cookies may impact the functionality and user experience of our website.

You can accept all cookies by clicking the "Accept" button or configure them or refuse their use by clicking HERE.