.
What is the usecase?
Suppose two models can be associated to a third model with a common attribute. For example, Image can belong to User as well as Product, because user will have self image and product will have descriptive images of product.
This can be achieved with Polymorphic associations - Two or more models can be associated to third model using single association.
How to use it?
Let’s understand how to use it. There are two parts -
- Migration defining two fields on the model which will have work as base model. It will have
association_id->intandassociation_type->string. - Defining associations in models.
And we are ready to use it.
Lets understand through code example.
Code Example
Suppose we have three models - Picture, User, Product. We need specify polymorphic association at
pictures table creation
1. Migration
We will add two fields imageable_type and imageable_id.

2. Model associations changes

What if we do not use Polymorphic?
We will have to create two tables representing User-Image and Product-Image associations. That will be
storing same attributes in two tables except user_id and product_id.
Benefits
The setup provides easy access to associated models.
- From an instance of the User model, you can retrieve a collection of pictures:
@user.pictures - Similarly, you can retrieve
@product.pictures - If you have an instance of the Picture model, you can get to its parent via
@picture.imageable - Polymorphic association helps in making your code DRY(Do not Repeat Yourself)
Can we test polymorphic associations?
Yes, of course. I am using rspec for unit testing instead of minitest. It can be installed from here
install rails rspec.
If you had not installed rspec previously, run
$ rails generate rspec:model user
create spec/models/user_spec.rb
$ rails generate rspec:model product
create spec/models/product_spec.rb
$ rails generate rspec:model picture
create spec/models/picture_spec.rb
Now we have empty rspec files for models. Let’s add following code to picture model rspec file

And when we run this spec file

It will pass with flying colors!
References -
Swapnil Gourshete
Multiple Inheritance in Ruby