Extensions

ROM

The ROM extension adds transaction support to your operations when working with the ROM database persistence toolkit. When a step returns a Failure, the transaction will automatically roll back, ensuring data consistency.

First, make sure you have rom-sql installed:

gem "rom-sql"

Require and include the extension in your operation class and provide access to the ROM container through a #rom method:

require "dry/operation/extensions/rom"

class CreateUser < Dry::Operation
  include Dry::Operation::Extensions::ROM

  attr_reader :rom

  def initialize(rom:)
    @rom = rom
    super()
  end

  def call(input)
    transaction do
      user = step create_user(input)
      step assign_role(user)
      user
    end
  end

  # ...
end

By default, the :default gateway will be used. You can specify a different gateway either when including the extension:

include Dry::Operation::Extensions::ROM[gateway: :my_gateway]

Or at runtime:

transaction(gateway: :my_gateway) do
  # ...
end

Sequel

The Sequel extension provides transaction support for operations when using the Sequel database toolkit. It will automatically roll back the transaction if any step returns a Failure.

Make sure you have sequel installed:

gem "sequel"

Require and include the extension in your operation class and provide access to the Sequel database object through a #db method:

require "dry/operation/extensions/sequel"

class CreateUser < Dry::Operation
  include Dry::Operation::Extensions::Sequel

  attr_reader :db

  def initialize(db:)
    @db = db
    super()
  end

  def call(input)
    transaction do
      user_id = step create_user(input)
      step create_profile(user_id)
      user_id
    end
  end

  # ...
end

You can pass options to the transaction either when including the extension:

include Dry::Operation::Extensions::Sequel[isolation: :serializable]

Or at runtime:

transaction(isolation: :serializable) do
  # ...
end

⚠️ Warning: The :savepoint option for nested transactions is not yet supported.

ActiveRecord

The ActiveRecord extension adds transaction support for operations using the ActiveRecord ORM. Like the other database extensions, it will roll back the transaction if any step returns a Failure.

Make sure you have activerecord installed:

gem "activerecord"

Require and include the extension in your operation class:

require "dry/operation/extensions/active_record"

class CreateUser < Dry::Operation
  include Dry::Operation::Extensions::ActiveRecord

  def call(input)
    transaction do
      user = step create_user(input)
      step create_profile(user)
      user
    end
  end

  # ...
end

By default, ActiveRecord::Base is used to initiate transactions. You can specify a different class either when including the extension:

include Dry::Operation::Extensions::ActiveRecord[User]

Or at runtime:

transaction(User) do
  # ...
end

This is particularly useful when working with multiple databases in ActiveRecord.

You can also provide default transaction options when including the extension:

include Dry::Operation::Extensions::ActiveRecord[isolation: :serializable]

You can override these options at runtime:

transaction(isolation: :serializable) do
  # ...
end

⚠️ Warning: The :requires_new option for nested transactions is not yet fully supported.

octocatEdit on GitHub