Polymorphic associations are little tricky to understand and many get confused on how to use them and how they are different from other association. We shall get even more vivid picture about polymorphic associations in this article.
With polymorphic associations, a model can belong to more than one other model, on a single association. Let’s take an example.
Say we can comment either on the photo or the event. So let’s have models Event, Photo and Comment. So now, Comment
model need to belong to both Event
and Photo
models on a single association. The association would look like the below:
class Comment < ApplicationRecord belongs_to :commentable, polymorphic: true end class Photo < ApplicationRecord has_many :comments, as: :commentable end class Event < ApplicationRecord has_many :comments, as: :commentable end
The migration for above association would have commentable_id
as foreign key and commentable_type
on the Comment table.
class CreateComments < ActiveRecord::Migration def change create_table :comments do |t| t.string :content t.integer :commentable_id t.string :commentable_type t.timestamps end end end
A polymorphic belongs_to
declaration is setting up an interface that any other model can use. From an instance of the Phoyo model, you can retrieve a collection of comments: @photo.comments
Similarly, you can retrieve @event.comments
If you have an instance of the Comment model, you can get to its parent via @comment.commentable
.
Loading development environment (Rails 4.1.1) 2.0.0-p247 :001 > photo = Photo.create(name: 'landscape') 2.0.0-p247 :002 > comment = Comment.create(content: 'good landscape picture') 2.0.0-p247 :003 > comment.update(commentable: photo) => true 2.0.0-p247 :004 > Photo.first.comments.first.content => "good landscape picture" 2.0.0-p247 :005 > event = Event.create(name: 'Cultural fest') 2.0.0-p247 :006 > comment = Comment.create(content: 'samskruthi 2017 rocks') 2.0.0-p247 :007 > comment.update(commentable: event) => true 2.0.0-p247 :008 > Event.first.comments.first.content => "samskruthi 2017 rocks" 2.0.0-p247 :009 > Comment.last.event.name => "Cultural fest" 2.0.0-p247 :0010 > Comment.first.photo.name => "landscape"