Polymorphic associations let one model belong to more than one other model using a single association. This helps keep your code simple and flexible.
Polymorphic associations in Ruby on Rails
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
The model with belongs_to uses polymorphic: true.
The other models use has_many with as: :association_name.
class Picture < ApplicationRecord has_many :tags, as: :taggable end class Article < ApplicationRecord has_many :tags, as: :taggable end class Tag < ApplicationRecord belongs_to :taggable, polymorphic: true end
class Like < ApplicationRecord belongs_to :likeable, polymorphic: true end class Video < ApplicationRecord has_many :likes, as: :likeable end class BlogPost < ApplicationRecord has_many :likes, as: :likeable end
This example shows how comments can belong to either a post or a photo. We create a post and a photo, then add comments to each. Finally, we print the comment bodies.
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 # Usage example in Rails console: post = Post.create(title: "My Post") photo = Photo.create(title: "My Photo") comment1 = Comment.create(body: "Great post!", commentable: post) comment2 = Comment.create(body: "Nice photo!", commentable: photo) puts post.comments.first.body puts photo.comments.first.body
Remember to add commentable_type and commentable_id columns in the comments table.
Polymorphic associations simplify your database by using one table for multiple relationships.
Polymorphic associations let one model belong to many others using one interface.
Use belongs_to :name, polymorphic: true and has_many :name, as: :name.
This keeps your code DRY and flexible for different related models.
Practice
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 AQuick Check:
Polymorphic association = flexible belongs_to [OK]
- Thinking it creates one-to-one relationships
- Confusing with database foreign key constraints
- Assuming it auto-generates views
Solution
Step 1: Recall belongs_to polymorphic syntax
The correct syntax usesbelongs_to :name, polymorphic: truein 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 DQuick 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
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?Solution
Step 1: Understand polymorphic type storage
The polymorphic association stores the class name of the associated object incommentable_type.Step 2: Identify the associated model
The comment belongs to a Post, socommentable_typewill be "Post".Final Answer:
"Post" -> Option CQuick Check:
commentable_type stores class name = "Post" [OK]
- Confusing commentable_type with comment class
- Expecting the associated object instead of its type string
- Assuming nil if association exists
class Picture < ApplicationRecord belongs_to :imageable, polymorphic: true end
Which of these will cause an error when creating a Picture?
Solution
Step 1: Check required polymorphic keys
Polymorphic belongs_to requires bothimageable_typeandimageable_idto be present for a valid association.Step 2: Identify missing or nil values
Picture.create(imageable_type: nil, imageable_id: 2) hasimageable_type: nil, which breaks the association and causes an error.Final Answer:
Picture.create(imageable_type: nil, imageable_id: 2) -> Option AQuick Check:
Missing polymorphic type causes error [OK]
- Assuming nil imageable_type is acceptable
- Ignoring missing type causes runtime error
- Confusing polymorphic keys with normal foreign keys
Solution
Step 1: Identify polymorphic association pattern
Comments belong to a polymorphiccommentableinterface, 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 usesbelongs_to :commentable, polymorphic: truein Comment andhas_many :comments, as: :commentablein Article and Event.Final Answer:
polymorphic belongs_to and has_many as: :commentable -> Option BQuick 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]
- Trying to belongs_to both models separately
- Using has_many in Comment instead of belongs_to
- Assigning belongs_to comment in parent models
Ready to prove it?
Pass the test and this pattern moves unknown
