# How to use dry-validation with dry-transaction?

**URL:** <https://discourse.dry-rb.org/t/how-to-use-dry-validation-with-dry-transaction/1588>\
**Category:** dry-validation\
**Created:** [December 30, 2022, 2:49pm UTC](https://discourse.dry-rb.org/t/how-to-use-dry-validation-with-dry-transaction/1588 "2022-12-30T14:49:21Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![jignesh](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/jignesh/32/832_2.png) [@jignesh](https://discourse.dry-rb.org/u/jignesh)\
**Post date:** [December 30, 2022, 2:49pm UTC](https://discourse.dry-rb.org/t/how-to-use-dry-validation-with-dry-transaction/1588/1 "2022-12-30T14:49:21Z")

</div>

Hello,

At [dry-rb - dry-transaction v0.13 - Wrapping operations](https://dry-rb.org/gems/dry-transaction/0.13/wrapping-operations/) following example is given:

```auto
class CreateUser
  include Dry::Transaction(container: Container)

  step :validate, with: "users.validate"
  step :create, with: "users.create"

  private

  def validate(input)
    adjusted_input = upcase_values(input)
    super(adjusted_input)
  end

  def upcase_values(input)
    input.each_with_object({}) { |(key, value), hash|
      hash[key.to_sym] = value.upcase
    }
  end
end

```

```auto
require "dry/container"
require "dry/transaction"
require "dry/transaction/operation"

module Users
  class Validate
    include Dry::Transaction::Operation

    def call(input)
      # returns Success(valid_data) or Failure(validation)
    end
  end

  class Create
    include Dry::Transaction::Operation

    def call(input)
      # returns Success(user)
    end
  end
end

```

Now is it possible to make `Users::Validate` look like

```auto
module Users
  class Validate
    include Dry::Transaction::Operation

    # Question: Is following possible?
    params do
      required(:email).value(:string)
      required(:age).value(:integer)
    end

    def call(input)
      # returns Success(valid_data) or Failure(validation)
    end
  end
end

```

Basically what I am trying to ask is can the input validations be defined directly inside a step (or in a transaction itself) without requiring to first define an explicit validation contract like it is illustrated at [dry-rb - dry-validation v1.8 - Introduction](https://dry-rb.org/gems/dry-validation/1.8/#quick-start) and then running that contract?

If no, then is there any recommended pattern in dry-style regarding validating inputs in a transaction?

Thanks.

---

<div class="post-metadata">

**Author:** ![alassek](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/alassek/32/314_2.png) [@alassek](https://discourse.dry-rb.org/u/alassek)\
**Post date:** [January 4, 2023, 6:37pm UTC](https://discourse.dry-rb.org/t/how-to-use-dry-validation-with-dry-transaction/1588/2 "2023-01-04T18:37:21Z")

</div>

Sure, you just need to override the output of `call` to coerce it to a monad. Here’s a working example:

```ruby
#!/usr/bin/env ruby
# frozen_string_literal: true

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'dry-transaction'
  gem 'dry-validation'
end

require 'dry/transaction'
require 'dry/transaction/operation'
require 'dry/validation'

Dry::Validation.load_extensions(:monads)

module Users
  class Validate < Dry::Validation::Contract
    include Dry::Transaction::Operation

    params do
      required(:email).value(:string)
      required(:age).value(:integer)

      before(:value_coercer) do |result|
        result.to_h.transform_values(&:upcase)
      end
    end

    def call(...) = super.to_monad
  end
end

Container = Dry::Core::Container.new

Container.register("users.validate") { Users::Validate.new }

class CreateUser
  include Dry::Transaction(container: Container)

  step :validate, with: "users.validate"
end

puts CreateUser.new.({ email: "john.doe@example.com", age: "23" }).inspect

```
