Altcademy - a Forbes magazine logo Best Coding Bootcamp 2023

What is Polymorphic Associations in Ruby on Rails?

Polymorphic Associations is a powerful concept in Ruby on Rails that allows you to represent relationships between different models in a more flexible and reusable way. In this post, we'll explore what Polymorphic Associations are, why they're useful, and how to implement them in a Rails application. We'll also provide code examples and analogies to help illustrate the concepts.

Understanding Associations in Rails

Before diving into Polymorphic Associations, let's first take a look at the basics of associations in Rails. Associations are a way of establishing relationships between different models in your application. They allow you to define how your data is connected and simplify the way you interact with your data.

There are three common types of associations in Rails:

  1. One-to-one
  2. One-to-many
  3. Many-to-many

For example, let's consider a simple blogging application where we have two models: Author and Post. An author can have many posts, and each post belongs to an author. This is an example of a one-to-many association.

To define this association in Rails, we would do the following:

class Author < ApplicationRecord
  has_many :posts
end

class Post < ApplicationRecord
  belongs_to :author
end

This simple code allows us to easily interact with our data and perform operations such as creating a new post for an author, retrieving all posts for an author, and finding the author for a given post.

Limitations of Basic Associations

While the basic associations in Rails are powerful and easy to use, they do have some limitations. One such limitation is that they can only represent relationships between two specific models. In other words, if you have a Comment model and you want to associate it with both Post and Author, you would need to create separate associations for each.

This can lead to a lot of duplicated code and make your application more difficult to maintain. This is where Polymorphic Associations come in.

Introducing Polymorphic Associations

Polymorphic Associations are a way of representing relationships between multiple models without duplicating code. They allow you to create a single association that can be reused across different models.

Let's go back to our blogging example and add a new requirement: users can leave comments on both posts and authors. Without polymorphic associations, we would need to create separate associations for each, like this:

class Comment < ApplicationRecord
  belongs_to :post
  belongs_to :author
end

This would work, but it's not very flexible or reusable. If we wanted to add comments to another model in the future, we would need to create yet another association. This is where Polymorphic Associations can help.

To create a polymorphic association, we'll make a small change to our Comment model:

class Comment < ApplicationRecord
  belongs_to :commentable, polymorphic: true
end

This tells Rails that the Comment model can belong to any other model, and we'll use the commentable field to specify which model it belongs to. Now, we just need to update our Post and Author models to indicate that they can have comments:

class Post < ApplicationRecord
  belongs_to :author
  has_many :comments, as: :commentable
end

class Author < ApplicationRecord
  has_many :posts
  has_many :comments, as: :commentable
end

That's it! We now have a flexible and reusable way of associating comments with both posts and authors.

Working with Polymorphic Associations

Now that we've set up our polymorphic association, let's explore how to interact with it. The good news is that it's very similar to working with regular associations.

To create a new comment for a post, we can do the following:

post = Post.find(1)
comment = post.comments.create(content: 'Great post!')

This will create a new comment with the commentable_id set to the ID of the post and the commentable_type set to "Post". Similarly, we can create a comment for an author like this:

author = Author.find(1)
comment = author.comments.create(content: 'I love your work!')

To retrieve all comments for a post or author, we can simply call the comments method:

post_comments = post.comments
author_comments = author.comments

And to find the parent model for a comment, we can use the commentable method:

parent = comment.commentable

This will return either a Post or Author instance, depending on the type of the parent.

Benefits of Polymorphic Associations

As we've seen, Polymorphic Associations provide a flexible and reusable way of representing relationships between multiple models. Here are some benefits of using them:

  1. Code Reusability: By using a single association for multiple models, we can avoid duplicating code and make our application easier to maintain.
  2. Flexibility: Polymorphic Associations make it easy to add new relationships between models without having to create additional associations.
  3. Simplicity: They simplify the way we interact with our data, making it easier to perform operations like creating and retrieving related records.

An Additional Example: Likes

To further illustrate the concept of polymorphic associations, let's consider another common scenario: allowing users to "like" both posts and comments.

First, we'll create a new Like model with a polymorphic association:

class Like < ApplicationRecord
  belongs_to :user
  belongs_to :likeable, polymorphic: true
end

Next, we'll update our Post and Comment models to indicate that they can have likes:

class Post < ApplicationRecord
  belongs_to :author
  has_many :comments, as: :commentable
  has_many :likes, as: :likeable
end

class Comment < ApplicationRecord
  belongs_to :commentable, polymorphic: true
  has_many :likes, as: :likeable
end

Now, users can like both posts and comments using the same Like model, and we can easily retrieve all likes for a given post or comment:

post_likes = post.likes
comment_likes = comment.likes

This is just another example of how Polymorphic Associations can help us create more flexible and reusable relationships between our models.

Conclusion

Polymorphic Associations are a powerful feature in Ruby on Rails that allows you to represent relationships between multiple models in a more flexible and reusable way. By understanding and using this feature, you can create more maintainable and efficient applications. In this post, we've explored the basics of Polymorphic Associations, provided code examples, and demonstrated their benefits through real-world examples. We hope this helps you as you continue learning about Rails and its powerful features.