Polymorphic Associations Explained

Polymorphic associations in Ruby on Rails are a powerful feature that allows a single model to belong to multiple other models using a single association. This is particularly useful when you have a model that can be associated with more than one other model type, without having to specify the model types directly.

What is a Polymorphic Association?

A polymorphic association allows a model to belong to more than one other model using a single association. For instance, consider a scenario where you have Comment model that can belong to either a Post model or an Event model. Instead of creating separate associations for each possible owner, you can use a polymorphic association.

Setting Up Polymorphic Associations

Let’s set up a polymorphic association with a Comment model that can belong to either a Post or an Event.

Step 1: Generate Models

First, generate the necessary models:

1
2
3
rails generate model Post title:string body:text
rails generate model Event name:string description:text
rails generate model Comment body:text commentable:references{polymorphic}

Step 2: Migrate the Database

Run the migrations to create the database tables:

1
rails db:migrate

The comments table will have the following columns: id, body, commentable_type, commentable_id, created_at, and updated_at. The commentable_type and commentable_id columns will store the type and ID of the associated model.

Step 3: Define the Associations

Next, set up the associations in your models.

Post Model:

1
2
3
class Post < ApplicationRecord
  has_many :comments, as: :commentable
end

Event Model:

1
2
3
class Event < ApplicationRecord
  has_many :comments, as: :commentable
end

Comment Model:

1
2
3
class Comment < ApplicationRecord
  belongs_to :commentable, polymorphic: true
end

Using Polymorphic Associations

Now that the associations are set up, you can create comments for both posts and events.

Creating a Post with Comments:

1
2
3
post = Post.create(title: "First Post", body: "This is the body of the first post")
comment1 = post.comments.create(body: "Great post!")
comment2 = post.comments.create(body: "Thanks for sharing!")

Creating an Event with Comments:

1
2
3
event = Event.create(name: "Rails Conference", description: "Annual Ruby on Rails conference")
comment1 = event.comments.create(body: "Looking forward to this event!")
comment2 = event.comments.create(body: "Can't wait to attend!")

Accessing Comments:

You can access comments for a post or an event through their respective associations.

1
2
post_comments = post.comments
event_comments = event.comments

Finding the Commentable:

You can also find out the commentable object (either a post or an event) for a comment.

1
2
3
comment = Comment.find(1)
commentable = comment.commentable
# commentable can be either a Post or an Event

Benefits of Polymorphic Associations

  1. Flexibility: Polymorphic associations provide flexibility by allowing a model to belong to more than one other model type.
  2. DRY (Don’t Repeat Yourself): They help to keep your code DRY by avoiding the need for multiple associations for different models.
  3. Simplicity: They simplify the schema and codebase by reducing the number of tables and associations.

Polymorphic associations in Ruby on Rails are a robust way to handle situations where a model needs to belong to multiple other models. By understanding and utilizing polymorphic associations, you can create flexible, maintainable, and scalable Rails applications.