Polymorphic Associations

Polymorphic Associations are a method for dealing with database models that have some sort of logical relationship. One model can belong to many other models on a single association. What this means is that a model can have many one-to-one relationships with other models. Lets see if an example explains this a bit better.

I am going to try and explain this in a way that is framework agnostic. The concept will hopefully be clear without being laden with details for a specific implementation.

Polymorphic Orders

Lets say you have an ordering system where users can come into a store, buy online, or pick out products from a mail order catalog. You handle this service as a merchant for many different sites, stores, and catalogs. You need to track all orders along with the source.

To do this polymorphically you will need four tables:

    - id
    - price
    - tax
    - orderable_id
    - orderable_type

    - id
    - name

    - id
    - name

    - id
    - name

Knowing that polymorphic associations allow you to tie models together on one association made you decide this was the perfect model, because you can only have a purchase at one store with one method at a time. Brilliant!

If you paid attention you might have noticed that orders has some awkwardly named columns that are not really words, but they make me sound smart. These columns are where the magic happens.

Column: orderable_id

The orderable_id column is what links the polymorphic association to the correct record id of whatever model it happens to be used with. This in essence functions like a foreign key.

Column: orderable_type

The orderable_type column will be a string name representing the class name of the model it is linking to.

Order Shipped:

The frameworks that use these types of associations all provide a different API for utilizing them. I am not sure if this is based on a pattern or if they are simply mirroring functionality because it is done elsewhere and expected. If anyone knows I would really like to hear about that.

These associations allow you to work both ways, if you have a record you can get to the parent type or the linking type.

order = Order.find(10)

# get the polymorphic parent

website = websites.find(100)

# get all of the orders

Package Delivered:

Hopefully I did a good enough job explaining this in an abstract enough way that you should at least have an understanding of what Polymorphic Associations are. Note there are also many-to-many representations of these associations which I will cover in another post.