Injecting operations
You can inject operation objects into transactions to adjust their behavior at runtime. This could be helpful to substitute operations with test doubles to simulate various conditions in testing.
You can inject operation objects for both ”external” steps (defined using with:
, pointing to a container registration), as well as “internal” steps (backed by instance methods only).
To inject operation objects, pass them as keyword arguments to the initializer, with their keyword matching their step's name.
Each injected operation must respond to #call(input, *args)
.
class CreateUser
include Dry::Transaction(container: Container)
step :prepare
step :validate, with: "users.validate"
step :create, with: "users.create"
private
def prepare(input)
Success(input)
end
end
prepare = -> input { Success(input.merge(name: "#{input[:name]}!!")) }
create = -> user { Failure([:could_not_create, user]) }
create_user = CreateUser.new(prepare: prepare, create: create)
create_user.call(name: "Jane", email: "jane@doe.com")
# => Failure([:could_not_create, {:name => "Jane!!", :email => "jane@doe.com"})