-
Notifications
You must be signed in to change notification settings - Fork 1
Interactor
Interactor encapsulates your business logic. Interactor is a simple object with an only one goal.
Methodist interactors work using dry-transaction
It's simple. Just create your interactor with:
rails generate interactor hello/world
This command will generate a file #{Rails.root}/app/interactors/hello/world.rb with code:
class Hello::World < Methodist::Interactor
schema do
# schema code goes here
end
step :validate
endAs you can see in the class body we have #schema method with the pass block.
We need it for validation. We have step :validate below, where step is one of a step adapter from
dry-transaction and :validate is a validation method.
You should read this doc to
understand how does the step adapter work. Learn more about validations below.
Now add a validation schema and one more step to our interactor:
class Hello::World < Methodist::Interactor
schema do
required(:name).value(:str?)
end
step :validate
step :say_hello
def say_hello(input)
puts "Hello, #{input[:name]}"
Success(input)
end
endWe define #say_hello but don't define #validate. Why? Because #validate has already defined in a
Methodist::Interactor class. You can redefine it after your steps.
Now you can use our first interactor:
Hello::World.new.call(name: 'QNester')
#> Hello, QNester
#> Success({ name: 'QNester' })You can check the interactor execution result:
result = Hello::World.new.call(name: 'QNester')
result.success? #> true
result.value #> { name: 'QNester' }Learn more about dry-transaction behavior here: http://dry-rb.org/gems/dry-transaction/basic-usage/
Methodist interactors have a built-in validation mechanism by dry-validation
To use built in #validate method in your interactors, pass your validations to the #shema method.
Example:
# app/interactors/hello/world.rb
class Hello::World < Methodist::Interactor
schema do
required(:name).value(:str?)
end
step :validate
step :say_hello
def say_hello(input)
puts "Hello, #{input[:name]}"
Success(input)
end
end
# success
result = Hello::World.new.call(name: 'QNester')
result.success? #> true
# failure
another_result = Hello::world.new.call
another_result.success? #> false
another_result.value #> { error: 'ValidationError', field: :name, reason: 'name: must exists' }If you want to customize the value returned in case of validation failure, redefine a #failure_validation_value method.
To create your own validation method, use one of these approaches:
- redefine a
#validatemethod; - define
#your_custom_methodand use it like thatstep :your_custom_methodinstead ofstep :validate.
About dry-validation schemas here.