Getting Started » Setup DSL

This guide explains how to quickly configure ROM using setup DSL, which is suitable for simple scripts.

ROM & frameworks

If want to use ROM with a framework, see specific instructions in the getting started section.


The configuration options explained in this document are the same for Explicit Setup using ROM::Configuration object

Connect to a single database

Call ROM.container with the adapter symbol and configuration details for that adapter:

# This creates a rom-sql adapter backed by SQLite in-memory database
ROM.container(:sql, 'sqlite::memory') do |config|
  # define relations and commands here...

# You can provide additional connection options too
ROM.container(:sql, 'postgres://localhost/my_db', extensions: [:pg_json]) do |config|
  # define relations and commands here...

# ROM also comes with a very barebones in-memory adapter.
ROM.container(:memory, 'memory://test') do |config|
  # define relations and commands here...

Connect to multiple databases

Sometimes you have multiple data sources. You can provide multiple gateway configurations with a name hash.

# Example: an old mysql database, “tasks”, and a new database “task_master”
# This registers two rom-sql adapters and then labels postgres with “default” and mysql with “legacy”
  default: [:sql, 'postgres://localhost/task_master'], # gateway 1
  legacy: [:sql, 'mysql2://localhost/tasks']           # gateway 2
) do |config|
    # setup code goes here...

If there is only one adapter provided, then its identifier is automatically set to :default:

# This setup call...
ROM.container(:sql, 'sqlite::memory')

# is equivalent to this one:
ROM.container(default: [:sql, 'sqlite::memory'])

Access the container

ROM.container always returns the finalized environment container object. This object is not global, and it must be managed either by you or a framework that you use.

rom = ROM.container(:sql, 'sqlite::memory') do |config|
  # define relations and commands here...

ActiveRecord and DataMapper provide global access to their components, but this is considered a bad practice in modern standards. ROM creates an isolated, local container without polluting global namespaces. This allows you to easily pass it around without being worried about accidental side-effects like conflicting database connections or configurations being overridden in a non-thread-safe way


Learn how to read data via Repositories and Relations.