📖 Scenario: You are building a simple Rails app where users can comment on different types of content: articles and photos. Instead of creating separate comment tables for each content type, you will use polymorphic associations to let comments belong to either articles or photos.
🎯 Goal: Create a Rails setup where Comment can belong to either an Article or a Photo using polymorphic associations.
📋 What You'll Learn
Create Article and Photo models with a title attribute
Create a Comment model that belongs to a polymorphic commentable
Set up the associations in all models correctly
Demonstrate creating comments for both articles and photos
💡 Why This Matters
🌍 Real World
Polymorphic associations let you reuse one model (like Comment) for many different related models (like Article and Photo) without duplicating tables or code.
💼 Career
Understanding polymorphic associations is important for Rails developers to design flexible and maintainable database relationships in real applications.
Progress0 / 4 steps
1
Create Article and Photo models
Create two Rails models called Article and Photo. Each model should have a string attribute called title. Use Rails generators or write the model classes with title attribute.
Ruby on Rails
Hint
Use rails generate model Article title:string and rails generate model Photo title:string or define classes with title attribute.
2
Add Comment model with polymorphic association
Create a Rails model called Comment with a string attribute body. Add polymorphic references commentable to this model. This means Comment belongs to commentable polymorphically.
Ruby on Rails
Hint
Use rails generate model Comment body:string commentable:references{polymorphic} or define the class with belongs_to :commentable, polymorphic: true.
3
Set up associations in Article and Photo models
In the Article and Photo models, add the association to comments using has_many :comments, as: :commentable. This sets up the polymorphic connection from the other side.
Ruby on Rails
Hint
Add has_many :comments, as: :commentable inside both Article and Photo classes.
4
Create comments for articles and photos
Write code to create an Article with title 'Rails Guide' and a Photo with title 'Sunset'. Then create a Comment with body 'Great article!' for the article, and a Comment with body 'Beautiful photo!' for the photo. Use the polymorphic association to link comments.
Ruby on Rails
Hint
Create instances of Article and Photo with the given titles. Then create Comment instances linking to these using commentable: option.
Practice
(1/5)
1. What is the main purpose of polymorphic associations in Rails?
easy
A. To allow a model to belong to more than one other model using a single association
B. To create a one-to-one relationship between two models
C. To enforce database constraints on foreign keys
D. To automatically generate views for multiple models
Solution
Step 1: Understand polymorphic association concept
Polymorphic associations let one model belong to multiple other models through a single interface.
Step 2: Compare options with concept
To allow a model to belong to more than one other model using a single association correctly describes this flexibility. Other options describe unrelated features.
Final Answer:
To allow a model to belong to more than one other model using a single association -> Option A
Quick Check:
Polymorphic association = flexible belongs_to [OK]
Hint: Polymorphic means one interface for many models [OK]
Common Mistakes:
Thinking it creates one-to-one relationships
Confusing with database foreign key constraints
Assuming it auto-generates views
2. Which of the following is the correct syntax to declare a polymorphic belongs_to association in a Rails model?
easy
A. has_many :commentable, polymorphic: true
B. has_one :commentable, polymorphic: true
C. belongs_to :commentable, as: :polymorphic
D. belongs_to :commentable, polymorphic: true
Solution
Step 1: Recall belongs_to polymorphic syntax
The correct syntax uses belongs_to :name, polymorphic: true in the model that belongs to multiple types.
Step 2: Match options with syntax
belongs_to :commentable, polymorphic: true matches this exactly. Options A and D use wrong association types, and C uses incorrect keyword.
Final Answer:
belongs_to :commentable, polymorphic: true -> Option D
Quick Check:
belongs_to with polymorphic: true = belongs_to :commentable, polymorphic: true [OK]
Using has_many instead of belongs_to for polymorphic
Using 'as: :polymorphic' instead of 'polymorphic: true'
Confusing has_one with belongs_to
3. Given these models:
class Comment < ApplicationRecord
belongs_to :commentable, polymorphic: true
end
class Post < ApplicationRecord
has_many :comments, as: :commentable
end
class Photo < ApplicationRecord
has_many :comments, as: :commentable
end
What will post.comments.first.commentable_type return if the first comment belongs to a Post?
medium
A. "Photo"
B. "Comment"
C. "Post"
D. nil
Solution
Step 1: Understand polymorphic type storage
The polymorphic association stores the class name of the associated object in commentable_type.
Step 2: Identify the associated model
The comment belongs to a Post, so commentable_type will be "Post".
Final Answer:
"Post" -> Option C
Quick Check:
commentable_type stores class name = "Post" [OK]
Hint: commentable_type holds the class name of associated model [OK]
Common Mistakes:
Confusing commentable_type with comment class
Expecting the associated object instead of its type string
Assuming nil if association exists
4. You have this model:
class Picture < ApplicationRecord
belongs_to :imageable, polymorphic: true
end
Which of these will cause an error when creating a Picture?
medium
A. Picture.create(imageable_type: nil, imageable_id: 2)
B. Picture.create(imageable_type: "Product", imageable_id: 2)
C. Picture.create(imageable_type: "User", imageable_id: 1)
D. Picture.create(imageable_type: "User", imageable_id: 3)
Solution
Step 1: Check required polymorphic keys
Polymorphic belongs_to requires both imageable_type and imageable_id to be present for a valid association.
Step 2: Identify missing or nil values
Picture.create(imageable_type: nil, imageable_id: 2) has imageable_type: nil, which breaks the association and causes an error.
Final Answer:
Picture.create(imageable_type: nil, imageable_id: 2) -> Option A
Quick Check:
Missing polymorphic type causes error [OK]
Hint: Both type and id must be present for polymorphic belongs_to [OK]
Common Mistakes:
Assuming nil imageable_type is acceptable
Ignoring missing type causes runtime error
Confusing polymorphic keys with normal foreign keys
5. You want to add comments to both Articles and Events using polymorphic associations. Which setup correctly models this?
hard
A. class Comment < ApplicationRecord
belongs_to :article
belongs_to :event
end
B. class Comment < ApplicationRecord
belongs_to :commentable, polymorphic: true
end
class Article < ApplicationRecord
has_many :comments, as: :commentable
end
class Event < ApplicationRecord
has_many :comments, as: :commentable
end
C. class Comment < ApplicationRecord
has_many :articles
has_many :events
end
D. class Article < ApplicationRecord
belongs_to :comment
end
class Event < ApplicationRecord
belongs_to :comment
end
Solution
Step 1: Identify polymorphic association pattern
Comments belong to a polymorphic commentable interface, allowing multiple models to share comments.
Step 2: Match correct model declarations
class Comment < ApplicationRecord
belongs_to :commentable, polymorphic: true
end
class Article < ApplicationRecord
has_many :comments, as: :commentable
end
class Event < ApplicationRecord
has_many :comments, as: :commentable
end correctly uses belongs_to :commentable, polymorphic: true in Comment and has_many :comments, as: :commentable in Article and Event.
Final Answer:
polymorphic belongs_to and has_many as: :commentable -> Option B
Quick Check:
Polymorphic belongs_to + has_many as: = class Comment < ApplicationRecord
belongs_to :commentable, polymorphic: true
end
class Article < ApplicationRecord
has_many :comments, as: :commentable
end
class Event < ApplicationRecord
has_many :comments, as: :commentable
end [OK]
Hint: Use belongs_to polymorphic in child, has_many as: in parents [OK]
Common Mistakes:
Trying to belongs_to both models separately
Using has_many in Comment instead of belongs_to
Assigning belongs_to comment in parent models
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.