Working on a Rails project, I faced a problem similar to this: Given an ActiveRecordModel called Booking which can have multiple bills:
The amount of the Bill comes from the Booking’s amount:
Now we need a new model, Subscription, and a Subscription can also have a Bill so:
And here is the problem, it isn’t possible to delegate to both Booking and Subscription.
Ok, let’s stop thinking about Rails and try to solve this with OO and plain Ruby. In plain Ruby, the Bill class would probably look like this:
Then, when the Subscription entity enters the game, the only thing we need to take care of is the fact that Booking and Subscription have a common interface with one method amount. This can be written as follows:
Now, the Bill class doesn’t have to mind about Bookings or Subscriptions anymore.
Good, back to Rails. How do I model this in Rails? I would have to change the previous Rails code to something like this:
The answer is polymorphic associations. This type of association allows Bill to belong_to an interface. The only thing we have to do is mark this relation as polymorphic, and the Booking and Subscription models as billable
Maybe in a future post I dig into how Rails maps these models to the database, but that’s it for today. Here I leave other posts about Rails polymorphic associations that I found interesting: