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
- Flexibility: Polymorphic associations provide flexibility by allowing a model to belong to more than one other model type.
- DRY (Don’t Repeat Yourself): They help to keep your code DRY by avoiding the need for multiple associations for different models.
- 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.