What is Polymorphism

After watching week 2 of the Intermediate Ruby on Rails course, Matt uses a Polymorphic Model.

Can somebody please explain what this means, and when I would use a Polymorphic Model?

Thanks.

Polymorphism in general refers to having objects of different types that implement the same interface, so that you can treat them the same way without worrying about the type.

In Rails, a polymorphic association refers to an association that doesn’t care about the type of the object it points to.

Say we had a blog application with a BlogPost model and a Comment model. We’d probably set up associations like this:

class BlogPost < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :blog_post
end

When it tries to find the BlogPost for a Comment, Rails will look for a blog_post_id field on the comment model, and look up a BlogPost using that ID.

New we can change the application and introduce a Photo model. We also want comments on photos, so we can use a polymorphic association to association the Comment objects with an object of any type:

class Photo < ActiveRecord::Base
  has_many :comments, as: :commentable
end

class BlogPost < ActiveRecord::Base
  has_many :comments, as: :commentable
end

class Comment < ActiveRecord::Base
  belongs_to :commentable, polymorphic: true
end

Normally, if we used belongs_to :commentable Rails would look for a model called Commentable and a field on the Comment called commentable_id. The polymorphic: true option changes this; commentable is just a name for the association, it doesn’t refer to a real model. When we look up the commentable for a Comment Rails will use two fields on the Comment model: commentable_type and commentable_id. The commentable_type will hold the name of a class (e.g. "BlogPost" or "Photo") and the commentable_id will hold the ID.

On the other end of the association (has_many :comments, as: :commentable) we have to tell the BlogPost and Photo models that in this association they are playing the commentable role, that way when we load all the comments for a BlogPost (etc.) Rails knows to construct a query that looks for comments where the commentable_type is "BlogPost" and the commentable_id is the ID of the blog post we’re interested in.

I hope that helps, let me know if you have any more questions.

2 Likes

Thanks George. What would I ask myself or what are the signs that I would know when to use polymorphism?