Proper usage of dry-transaction with dry-validation

Currently in my organization, we are using dry-validation a lot with dry-transaction for the usual CRUD operations in our app. One thing that i find a bit weird is that we had to write a wrapper for the dry-validation schemas that looked like this to wrap the result of the schema in a dry-monad result

    result = schema.call(input)

    if result.success?
      Success(result.to_h)
    else
      Failure(result.errors)
    end

so upon digging a bit deeper, I found out that dry-validation schemas return Dry::Validation::Result instead of Dry::Monad::Result. So my questions would be…

  1. is there a better way to incorporate dry-validation with dry-transaction? (perhaps we’ve been using it wrong in our organization)
  2. are there plans to one day use dry-monad results as the result of dry-transaction schemas?

There’s already a method on Dry::Validation::Result to handle this: to_monad aka to_either

So you can shorten the code to

Dry::Validation.load_extensions(:monads)
result = schema.call(input)
result.to_monad

and then handle the to_h in the following step.

2 Likes

thanks @rickenharp. that does make it easier to work with schemas in the context of transactions. much cleaner too!

I on the other hand I use the validation output to create an entity and pass it along to the next steps for processing.

          if validation.success?
            Right(Entities::SomeEntity.new(validation.output))
          else
            Left(validation.errors)
          end