Introduction » Active Record and ROM
This document explains basic differences between Rails' Active Record ORM and ROM.
Supports only SQL.
Supports anything that can provide data, including SQL databases, NoSQL databases, CSV files, git repositories, remote HTTP APIs, anything. You can work with multiple databases at once and combine data in memory, if that's what you need.
Data access logic is part of the object and controls all reading and writing to the database. You use the same objects to create, read, update, and delete data. These objects are the models in traditional Rails applications.
Data manipulation is handled by a separate interface with user defined commands. Every relation that your application is going to use is explicitly defined. The ROM relations expose powerful internal query APIs that you use to create publicly accessible relation methods to return query results.
ActiveRecord models only exposed the scopes and scope methods to
the rest of the application. This is what ROM relations are like.
Models are at the heart of the pattern, and the library. As mentioned before, all data access is via the model. The assumption is that your application will only ever need a data representation that matches your database exactly. As the application grows, so does the likelihood that you need other ways to represent your data. In the Rails community this manifests as presenters, formatters, renderers, serializers, and so on.
All those objects that you create are nothing more than mapping. They take
ActiveRecord objects and represent them in a context sensitive way.
There is no single "model" object in ROM. ROM objects are instantiated by the mappers and have no knowledge about persistence. You can map to whatever structure you want and in common use-cases you can use repositories to automatically map query results to simple struct-like objects.
Mixes domain-specific data validation with persistence layer. An active record object validates itself using its own validation rules.
There's no validation concept built-in. Validations are handled externally by separate libraries and validated data can be passed down to the command layer to be persisted.
Handles coercion internally prior persisting data.
Coercion can be handled by relation schema attributes. Complex data transformations can be easily handled by repository changesets.