Polymorphism in Ruby and Rails

Joseph Glass
3 min readJul 24, 2017

--

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.

1. Subtyping

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.

When programming, it always pays to know the class of the data you’re working with. Receiving a string when you wanted an array, or an integer when you wanted a string can throw your code into a chaos of stack trace errors. Most languages know this and take measures to keep your data types separate and conversions explicit. Most. (I’m looking at you, JavaScript.) But let’s take a look at a time when we’d want sections of our code to be class-agnostic.

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!

So… many… joins tables…

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:

And voila!

There! Much better. One joins table Tagging plugs into three different models, thanks to our :polymorphic => true and our model-agnostic “taggable_type” field.

--

--