Last active
September 26, 2017 18:09
-
-
Save alebian/553c0d904aee6633f76b07f0672b15ce to your computer and use it in GitHub Desktop.
Mixin for Interactor objects. Dependencies: interactor, dry-types
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'interactor' | |
require 'dry-types' | |
# Author:: Alejandro Bezdjian | |
# Copyright:: Copyright (c) 2017 Alejandro Bezdjian | |
# License:: Apache 2.0 | |
class InteractorMixin | |
include Interactor | |
module Types | |
# Check out http://dry-rb.org/gems/dry-types | |
include Dry::Types.module | |
end | |
# Used to access attributes with bare words | |
def method_missing(method, *args, &block) | |
return context.send(method) if context.respond_to?(method) | |
super | |
end | |
def respond_to_missing?(method_name, include_private = false) | |
context.respond_to?(method) || super | |
end | |
def param(name, options = {}) | |
set_default!(name, options[:default]) | |
check_type!(name, options[:type]) | |
check_presence!(name, options[:required]) | |
end | |
def set_default!(name, value) | |
context[name] = value if attribute(name).nil? && present?(value) | |
end | |
def check_type!(name, type) | |
fail!("Expected #{name} to be #{type.name}") if present?(type) && invalid_type?(type, name) | |
end | |
def check_presence!(name, required) | |
fail!("Expected #{name} to be present") if attribute(name).nil? && required | |
end | |
def present?(object) | |
return false if object.nil? | |
true | |
end | |
# Method to get value from Interactor's context | |
def attribute(name) | |
context.send(name) | |
end | |
# Params: | |
# * +type+ - A class or a Dry::Type is expected | |
def valid_type?(type, attribute_name) | |
return type.valid?(attribute(attribute_name)) if type.respond_to?(:valid?) | |
attribute(attribute_name).is_a?(type) | |
end | |
# Params: | |
# * +type+ - A Dry::Type is expected | |
def invalid_type?(type, attribute_name) | |
!valid_type?(type, attribute_name) | |
end | |
# Method to stop Interactor's execution in one step | |
def fail!(message) | |
context.error = message | |
context.fail! | |
end | |
# Method used to add the final result to the Interactor object | |
def result(something) | |
context.result = something | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class TestInteractor < InteractorMixin | |
before do | |
param :param1, type: Types::String, required: true | |
param :param2, type: Types::Coercible::Float | |
param :param3, type: Pepe | |
end | |
def call | |
puts param1 | |
puts param2 | |
puts param3 | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment