At Aircall, we are dealing with a distributed Rails Legacy monolith. We are now splitting it progressively into lightweight Ruby-Sinatra microservices, and in order not to reproduce errors from the past, we started to implement new Architecture philosophies like Clean Architecture and Domain Driven Design. ROM was a really good match to us, as it fits really well in those philosophies.

In order to efficiently present ROM’s perks, we’ll see first what problems ActiveRecord brings, then what ROM is and its concepts and finally we’ll raise some attention points about this tool.

ActiveRecord limitations

When you are heading towards a better separation of concerns, you want to design your business logic without thinking first about which database you should use or how to persist data in an efficient way. When you’re designing an Application, you don’t know all your use cases right away, and your use cases should actually determine which kind of Datastore will be the most efficient.

ActiveRecord is easy to use when you’re bootstrapping an application, because you don’t have to enquire about how to build your persistence layer in an isolated and relevant way, everything (or almost everything) is done magically under the hood. But this shortcut becomes a nightmare when you’re scaling your application (when teams scale, in size and quantity or when your Application does more than just CRUD…) because this is when you end up complexifying your persistence layer with other technologies. This is also when you realize that your Models are fat and do a lot of different things, but it’s usually too late to split them following a proper Separation of Concerns, as it may be very expensive at this stage.

To me, one of the main problems with ActiveRecord (which is also its strength), is that it calls too many things “Model”. If you want to:

Write data (eventually with complex queries)

Fetch data in a particular way (with complex conditions for instance)

Build new attributes based on one that is already in database…

.. then there is a high probability that those will end up in your Models. This is one of the main perks of ROM: it doesn’t give the same name for each of those things.

ROM Concepts

If you want to know more about ROM, you can take a look here: https://rom-rb.org/5.0/learn/ . In this chapter, we’ll look at some core concepts and how they interact with each other.

ROM uses several concepts that could be represented this way*:

*Official schema and concepts definition: ROM core concepts

Yes sir! Here we go:

The Business layer is every piece of code that handles your business logic. It could be Controllers, Workers, Scripts, or even a CLI: