Skip to content

Instantly share code, notes, and snippets.

@parndt
Created June 8, 2023 22:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save parndt/7d3763afd5fe5d8dc673765d2b2e95d3 to your computer and use it in GitHub Desktop.
Save parndt/7d3763afd5fe5d8dc673765d2b2e95d3 to your computer and use it in GitHub Desktop.
hanami 2 action with dry-validation
module MySlice
module Actions
module Thing
class CreateContract < Dry::Validation::Contract
params do
required(:name).filled(:str?)
optional(:email).maybe(:str?)
end
rule(:email) do
# custom logic here e.g.
# key.failure("must be a valid email") unless value.match?(/@/)
end
end
class Create < Action
include Deps[repo: "repositories.thing"]
before :validate
params do
required(:thing).schema do
required(:name).filled(:str?)
optional(:email).maybe(:str?)
end
end
def handle(request, response)
case repo.create(response[:contract].to_h)
in {id: Integer} => thing
response.redirect_to routes.path(
:next_step,
id: thing.id
)
else
failure(request, response)
end
end
private def failure(request, response)
halt 422, response.render(
view,
thing: request.params[:thing],
errors: response[:contract].errors.to_h
)
end
private def validate(request, response)
response[:contract] = CreateContract.new.call(request.params[:thing])
failure(request, response) unless response[:contract].success?
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment