Changing a polymorphic_type in Rails

How my team redefined the way we store one of the polymorphic associations in the Shopify codebase. This post is the solution we wish we found when we were looking.

Diego Gilon
8 min readintermediate
--
View Original

Overview

This article discusses how the Payment Flexibility team at Shopify redefined the storage of polymorphic associations in Rails by transitioning from storing class names to arbitrary strings. This change aimed to reduce coupling between the codebase and the database, facilitating easier future modifications.

What You'll Learn

1

How to redefine polymorphic associations in Rails to use arbitrary strings instead of class names

2

Why reducing coupling between your codebase and database can simplify future changes

3

When to consider changing how polymorphic types are stored in your application

Prerequisites & Requirements

  • Basic understanding of Rails polymorphic associations
  • Familiarity with Active Record and database migrations(optional)

Key Questions Answered

How can you change the way Rails stores polymorphic associations?
You can change the storage method by redefining the polymorphic_name method to store arbitrary strings instead of class names. This allows for greater flexibility in renaming classes and modules without affecting the database records.
What are the benefits of not storing class names as polymorphic types?
Not storing class names as polymorphic types reduces the coupling between your codebase and database. This means you can rename or reorganize your classes and modules without needing to update existing database records, simplifying maintenance and future development.
What issues arise when changing namespaces in Rails polymorphic associations?
Changing namespaces can lead to multiple class name entries in the database, such as 'Car' and 'Garage::Car'. This results in broken associations, as Active Record may not recognize the new class names when querying related records.
When should you consider implementing arbitrary strings for polymorphic types?
You should consider this approach when you anticipate frequent changes to class names or namespaces. By using arbitrary strings, you can avoid the complications of updating the database each time a class is renamed or moved.

Technologies & Tools

Some links below are affiliate links. We may earn a commission if you make a purchase.

Key Actionable Insights

1
Consider redefining polymorphic associations to use arbitrary strings to enhance flexibility.
This approach allows for easier renaming and restructuring of classes without impacting existing database records, which can save time and reduce errors during future development.
2
Implement a strategy for cleaning up your database after transitioning to arbitrary strings.
Once you switch to using arbitrary strings, run migrations or scripts to ensure that all records reflect the new format. This will help maintain consistency and prevent confusion in your application.
3
Regularly review your database schema and associations to ensure they align with your current codebase structure.
This practice helps identify potential issues early, especially when making significant changes to your application's architecture.

Common Pitfalls

1
Failing to update existing records when changing the polymorphic type can lead to broken associations.
This happens because Active Record relies on the stored class names to find associated records. If the names change without updating the records, queries will fail to return the expected results.
2
Overcomplicating the transition process by not planning for future changes.
It's important to anticipate how your application's structure may evolve. If you don't consider future changes, you may end up with a rigid system that is difficult to maintain.

Related Concepts

Polymorphic Associations
Active Record
Database Migrations