ROM 2.0.0 Released

We’re happy to announce the release of rom 2.0 with a big list of improvements and new features! This release is a huge milestone for the project as its infrastructure is now complete - this means that all core APIs and high-level extensions are in place, and from now on it’s a matter of expanding functionality with new features.

Let’s take a quick look at the release highlights!

Relation Schemas

This new feature allows you to define a relation schema with attribute names and types.

By defining a relation schema you establish the canonical representation of the data provided by a relation. This gives you type-safe commands out-of-the-box and allows you to define custom types for low-level database coercions.

On top of that, every adapter can extend Schema API with its own features, and that’s how the new version of rom-sql adds support for defining associations.

Here’s an example:

class Users < ROM::Relation[:users]
  schema do
    attribute :id, Types::Serial
    attribute :name, Types::String

    associations do
      has_many :tasks
      belongs_to :group
    end
  end
end

You can learn more about relation schemas in the user documentation. For more information about associations check out SQL docs.

Command support in repositories

The new version of rom-repository adds support for database commands. This is a convenient API for common create/update/delete operations. It means there’s no need to define custom command classes for common operations anymore. Here’s an example:

class UserRepo < ROM::Repository[:users]
  commands :create, update: :by_pk, delete: :by_pk
end

# create
user = user_repo.create(name: "Jane")

# update
user_repo.update(user.id, name: "Jane Doe")

# delete
user_repo.delete(user.id)

Check out the user documentation for more information.

Repository changesets

Another new feature is the Changeset API, provided by rom-repository. This is a new way to handle data changesets via repository commands, similar to Elixir’s Ecto.

Changesets can be created via the Repository#changeset interface, here’s an example of “an update changeset”:

class UserRepo < ROM::Repository[:users]
  commands :create, update: :by_pk
end

user = user_repo.create(name: 'Jane', email: 'jane@doe.org')

changeset = user_repo.changeset(user.id, name: 'Jane Doe')

changeset.diff? # true
changeset.diff # {name=>"Jane Doe"}

user_repo.update(user.id, changeset)

This is a very fresh addition, please try it out and let us know what you think! You can learn more about it in the user documentation.

Native Upsert support for PostgreSQL >= 9.5

We added a new command type to rom-sql called Postgres::Upsert, this allows you to use native upsert statements on PostgreSQL. The repositories don't support it yet, but you can register commands manually and they will be available within the repositories.

Here's a full example of a setup with an Upsert command:

require 'rom-repository'
require 'rom-sql'
require 'rom/sql/commands/postgres'

conf = ROM::Configuration.new(:sql, 'postgres://localhost/rom_example')

conf.default.connection.create_table? :quotes do
  primary_key :id
  String :quote, unique: true, null: false
  Integer :likes, default: 1
end

class UpsertQuote < ROM::SQL::Commands::Postgres::Upsert
  relation :quotes
  register_as :create_or_update
  result :one

  conflict_target :quote
  update_statement likes: Sequel.+(:quotes__likes, 1)
end

conf.register_command(UpsertQuote)

class QuoteRepo < ROM::Repository[:quotes]
  def create_or_update(quote)
    command(:quotes)[:create_or_update].call(quote)
  end
end

rom = ROM.container(conf)

quote_repo = QuoteRepo.new(rom)

quote = quote_repo.create_or_update(quote: 'Such quote')

puts quote.inspect
# {:id=>1, :quote=>"Such quote", :likes=>1}

quote = quote_repo.create_or_update(quote: 'Such quote')

puts quote.inspect
# {:id=>1, :quote=>"Such quote", :likes=>2}

New website design & new documentation

Thanks to the awesome work of Angelo Ashmore, we’ve got a shiny new website design. We also updated the user docs and improved API docs coverage for most important rom gems.

We’re looking for help with adding guides, please check out the issues if you’re interested in contributing a guide.

Hanami and Trailblazer co-operation!

We started working closely with the Hanami and Trailblazer communities, looking into how our projects can help each other. As a result, we’ll be working on a rom-based backend for hanami-model, and integrating rom with Reform from Trailblazer.

These are really exciting times, we believe our co-operation will help us build a stronger ruby ecosystem!

What happens next?

We’d like to finish stable versions of rom-sql and rom-repository later this year. The core rom gem is already at version 2.0, but the main adapter and repositories are still unstable. There will be a lot of effort going into improving the query DSL in rom-sql, there are a lot of Sequel features that we could leverage and make the adapter even more powerful.

Depending on the feedback, we’ll also focus on expanding functionality of existing features and bug-fixing. Please report any issues on GitHub for individual rom projects that you use.

Gem updates summary

Please see the upgrade guide for more information about upgrading.

As part of this release following gems have been released:


ROM 1.0.0 Released

We're happy to announce the first stable release of rom core gem. It took us a little over a year to discover and implement the core interfaces that allow building rom adapters and extensions. Since no significant changes had to be made for many months and there are no outstanding issues - rom 1.0.0 is now available.

Following gems have been updated and released:

What Does This Release Mean?

This is a huge milestone even though it doesn't change a lot from the usage point of view. Having a stable set of core interfaces will make it easier to develop adapters and extensions and get them to a stable state, too. Up until now every ROM release was huge, including lots of changes in many places, multiple gems were released at the same time. These kind of releases are hard to manage and it's also difficult to provide information about individual changes and improvements without overwhelming current users and potential new users.

Now, with the stable rom core, we can focus on individual adapters and extensions. Release them separately, and probably more often. It will also make it simpler to explain and document changes and improvements.

What Happens Next?

First of all, we're working on updating rom-rb.org, which will have a new design and content - as the documentation is currently being rewritten. The initial set of docs was too focused on shared, lower-level APIs, mixed with adapter-specific APIs, which was confusing. New docs will focus on high-level guides specific to individual adapters, so it will be much easier to understand how to use ROM in a specific context.

As far as individual gems go, here's a rough plan:

  • rom
    • Relation schema support that can be used by commands and for migrations
    • Shared database migration interfaces for all adapters
  • rom-sql
    • Improvements in the query DSL, especially when it comes to building complex joins. We're still using Sequel but that may be changed in the near future.
    • Support for prepared statements
    • Built-in types for relation schemas specific to individual databases
  • rom-repository
    • Support for commands
    • Setup interface, that would make it simple to quickly configure gateway connection and fetch data
    • Support for dry-data structs and values
  • rom-model
    • ActiveModel::Validations will be replaced by dry-validation
    • ROM::Model::Attributes will be deprecated in favor of dry-validation schemas
  • rom-rails
    • Rewrite on top of dry-component
    • ROM::Model::Form will be deprecated

Apart from these improvements, there will be smaller clean ups, refactorings and performance tweaks.

The following adapters are looking for contributors and/or maintainers:

Please get in touch if your're interested in helping out :)

Towards rom 2.0, Stable Adapters and Repository

Further development of adapters and repository will very likely require changes in some of the core public APIs. Expect an evolution though, not a revolution. Some features will be introduced during 1.x.y upgrades, like relation schema, but any public API change will require a major version bump since rom follows SemVer. It's probably safe to assume this will happen later this year.

rom 2.0.0 will be a base for the first stable releases of individual adapters and extensions. That's why it is so important to focus on other adapters, not just rom-sql, to see what kind of improvements are needed and whether it's going to break any public APIs.

Providing Feedback And Reporting Issues

If you have found an issue or you're seeking help, there are number of ways you can get in touch:

  • Report an issue on GitHub, preferably in the issue tracker for the specific rom project. If you're not sure which one it is - don't worry and report it in the main rom issue tracker
  • Ask for help in the gitter channel
  • Post a message on our forum

If you've got feedback regarding documentation and/or the website, please report an issue in the rom-rb.org repo.

Thank You!

I'd like to use this opportunity to simply say "Thank You!" to everybody involved with the project. Many people have been supporting ROM in various ways, either by contributing bug fixes, adding features or making huge refactorings. There are also many people who have been very helpful in the gitter channel, providing support for others who were trying out ROM.

Really special thanks go to early adopters and contributors:

  • Alexander Flatter - for adopting rom very early, helping with API design, contributing code and supporting users in the channel
  • Andrew Kozin - for helping with rom-mapper, creating rom-migrator, rom-cassandra and rom-kafka
  • Andy Holland - for helping with rom core, creating rom-http and being supportive in the channel
  • Chris Flipse - who helped by providing patches and helping me with rom-rails and rom-yaml
  • Christopher Swasey - for his insane effort to refactor and improve rom setup interfaces
  • Don Morrison - for supporting me in the very early days of ROM, helping with adapter interface, documentation, rom-rb website and release announcements
  • Hannes Nevalainen - for testing things out early, providing awesome feedback and contributing to different rom projects
  • Mark Rickerby - who built rom-neo4j and helped with other projects, rom-rb website and release announcements
  • Oskar Szrajer - who helped a lot with rom-sql, rom-yesql, other adapters and patches in multiple rom projects as well as helped promoting rom at local Ruby meetups AND by providing support in our gitter channel
  • Peter Suschlik - for helping with performance improvements, support libs and helping with PRs. Peter is currently #3 comitter :)
  • Robin Miller - for helping with the new documentation and providing great feedback

I'm terribly sorry if I missed somebody! Thank you so much for helping with this enormous effort!

Happy 2016 :)


  • 2 of 7