What are polymorphic associations in rails?

According to the rails guide it is, "A slightly more advanced twist on associations". The term polymorphic association is more scary than the actual implementation of it.

Time to get to it and demystify this "slightly more advanced" association.

The Setup
rails g model BeerRecipe name:string style:string  
rails g model Ingredients name:string category:string  
# == Schema Information
#
# Table name: beer_recipes
#
#  id         :integer          not null, primary key
#  name       :string
#  style      :string
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class BeerRecipe < ActiveRecord::Base  
end  
# == Schema Information
#
# Table name: ingredients
#
#  id         :integer          not null, primary key
#  name       :string
#  category   :string
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class Ingredient < ActiveRecord::Base  
end  

We now have two models, BeerRecipe and Ingredient. A BeerRecipe can have a rating associated to it, as can an Ingredient. (We as homebrewers experiment with a lot of different types of ingredients. It's good to know whether we liked it or not.)

The Solution

If we went down the list of a homebrewing application we would quickly find that a lot of models would end up using a rating, so it would be nice to just have one Rating model and use it for every model that needed one.

We now want to create the Rating model and set it up for the polymorphic association.

rails g model Rating rateable_type:string rateable_id:integer stars:integer comments:text  

Once we have the Rating model created we want to go back in and modify the BeerRecipe and Ingredient models to allow for ratings.

# == Schema Information
#
# Table name: beer_recipes
#
#  id         :integer          not null, primary key
#  name       :string
#  style      :string
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class BeerRecipe < ActiveRecord::Base  
  has_many :ratings, as: :rateable
end  
# == Schema Information
#
# Table name: ingredients
#
#  id         :integer          not null, primary key
#  name       :string
#  type       :string
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class Ingredient < ActiveRecord::Base  
  has_many :ratings, as: :rateable
end  

I went in to rails console and added an entry to BeerRecipe and Ingredient. Then added a rating to each one. Below is the sql viewer for the ratings added to each.

Polymorphic Association

Once you see polymorphic associations in action they don't seem so confusing.

Now get out there and polymorph your entire app, but not really the whole thing, just the parts that would benefit from polymorphic associations, but if you really want to what could really go wrong?... but seriously don't.