DriedInteraction
DriedInteraction is a simple gem that helps you write interactors with input params validation.
Installation
Add this line to your application's Gemfile:
gem 'dried_interaction'
And then execute:
$ bundle
Or install it yourself as:
$ gem install dried_interaction
Usage
Setting up an interactor
For setting up an interactor you need to include DriedInteraction into your class. Then you can add contract for call method which will validate input params. By default interactor returns Dry::Matcher::ResultMatcher.
class PublishPost
include DriedInteraction
option :normalize_params, reader: :private, default: -> { PostParamsNormalize.new }
option :post_repo, reader: :private, default: -> { PostRepo }
option :notify, reader: :private, default: -> { PostNotify.new }
contract do
required(:user).filled(Dry.Types.Instance(User))
required(:params).hash do
required(:title).filled(:string)
required(:content).filled(:string)
optional(:public).filled(:bool)
end
end
def call(user:, params:)
normalized_params = yield normalize_params.call(params)
post = yield save_post(normalized_params)
notify.call(post)
Success(post)
end
private
def save_post(params)
post = post_repo.new(params)
post.save ? Success(post) : Failure('Error message')
end
end
Contract options
You can pass to contract some options which will customize contract logic.
-
kind
. Explains which type of validator you will use. Available values:simple
(By default) andextended
simple
kind uses simpleDry::Schema.Params
extended
kind uses more complexDry::Validation.Contract
contract(kind: :simple) do ... end
# or
contract(kind: :extended) do ... end
-
mode
. Explains how to handle contract validation errors. Available values:strict
(By default) andsoft
strict
mode raises exception when contract check fails.soft
mode returns Failure monad with error info when contract check fails.
contract(mode: :strict) do ... end # => raise DriedInteractionError
# or
contract(mode: :soft) do ... end # => returns Failure(DriedInteractionError)
Interactor calling
PublishPost.new.call({ user: user, params: params }) do |interactor|
interactor.success do |post|
# handle success
end
interactor.failure do |error|
# handle failure
end
end
When you use soft
mode you can handle contract failure as divided failure case:
PublishPost.new.call({ user: user, params: params }) do |interactor|
interactor.success do |post|
# handle success
end
interactor.failure(DriedInteractionError) do |error|
# handle contract validation error
end
interactor.failure do |error|
# handle failure
end
end
Contributing
- Fork it
- Create your feature branch (git checkout -b my-new-feature)
- Commit your changes (git commit -am 'Add some feature')
- Push to the branch (git push origin my-new-feature)
- Create new Pull Request
License
The gem is available as open source under the terms of the MIT License.