Module: Dry::Operation::Extensions::ActiveRecord

Defined in:
lib/dry/operation/extensions/active_record.rb

Overview

Add ActiveRecord transaction support to operations

When this extension is included, you can use a #transaction method to wrap the desired steps in an ActiveRecord transaction. If any of the steps returns a Dry::Monads::Result::Failure, the transaction will be rolled back and, as usual, the rest of the flow will be skipped.

require "dry/operation/extensions/active_record"

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

  def call(input)
    attrs = step validate(input)
    user = transaction do
      new_user = step persist(attrs)
      step assign_initial_role(new_user)
      new_user
    end
    step notify(user)
    user
  end

  # ...
end

By default, the ActiveRecord::Base class will be used to initiate the transaction. You can change this when including the extension:

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

Or you can change it at runtime:

user = transaction(user) do
  # ...
end

This is useful when you use multiple databases with ActiveRecord.

The extension can be initiated with default options for the transaction. It will be applied to all transactions:

include Dry::Operation::Extensions::ActiveRecord[requires_new: true]

You can override these options at runtime:

transaction(requires_new: false) do
  # ...
end

WARNING: Be aware that the `:requires_new` option is not yet supported.

Defined Under Namespace

Classes: Builder

Constant Summary collapse

DEFAULT_CONNECTION =
::ActiveRecord::Base

Class Method Summary collapse

Class Method Details

.[](connection = DEFAULT_CONNECTION, **options) ⇒ Object

Include the extension providing a custom class/object to initialize the transaction and default options.

Parameters:

  • connection (ActiveRecord::Base, #transaction) (defaults to: DEFAULT_CONNECTION)

    the class/object to use

  • options (Hash)

    additional options for the ActiveRecord transaction



87
88
89
# File 'lib/dry/operation/extensions/active_record.rb', line 87

def self.[](connection = DEFAULT_CONNECTION, **options)
  Builder.new(connection, **options)
end

.included(klass) ⇒ Object



78
79
80
# File 'lib/dry/operation/extensions/active_record.rb', line 78

def self.included(klass)
  klass.include(self[])
end