Polymorphism. One of the four fundamental pillars of Object Oriented Programing. A big word with a Greek etymology representing an even bigger concept.
But calm down, it’s actually pretty simple once you use it! This post is meant as a beginner’s introduction to polymorphic associations in Rails.
Polymorphism means many forms and (appropriately enough) there are several different types of polymorphism in programming.
One of the most common in Ruby is technically referred to as Subtyping or Subtype Polymorphism, but in OOP we just call it plain old Polymorphism. It is where a name refers to several different classes that all share a common superclass. Example time:
Here we see that Dog and Cat both inherit from the Mammal superclass. Because of that inheritance, they each have access to all the methods defined in their parent class. Dog and Cats are different forms of Mammal. Many-forms == Poly-morph.
In summary, Class Inheritance is the most common and basic form of Polymorphism
2. Polymorphic Associations
Now let’s talk about Parametric Polymorphism, sometimes called generics. Wikipedia defines parametric polymorphism as follows.
Parametric polymorphism: when code is written without mention of any specific type and thus can be used transparently with any number of new types.
I was writing a daily goal-tracking app and wanted to add a tagging system to keep track of goals, resources, and journal entries. Being the up-and-coming budding young programmer that I am, I thought “This is the perfect place for a joins table!
As you can see, three joins tables connect Goals, Journals, and Resources to tags. This is functional, but poor design. That’s a lot of duplication.
Polymorphic Associations to the rescue! Instead of having to make a separate joins table for each association, I just had to create one joins table of “Tagging” and the following associations in my model:
There! Much better. One joins table Tagging plugs into three different models, thanks to our :polymorphic => true and our model-agnostic “taggable_type” field.