Introduction » Active Record and ROM

This document explains basic differences between Rails' Active Record ORM and ROM.

Database Support

Active Record

Supports only SQL.

ROM

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

Active Record

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.

ROM

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.

Imagine that ActiveRecord models only exposed the scopes and scope methods to the rest of the application. This is what ROM relations are like.

Models

Active Record

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.

ROM

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.

Validation

Active Record

Mixes domain-specific data validation with persistence layer. An active record object validates itself using its own validation rules.

ROM

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.

Data Coercion

Active Record

Handles coercion internally prior persisting data.

ROM

Coercion can be handled by relation schema attributes. Complex data transformations can be easily handled by repository changesets.