Skip to content

Instantly share code, notes, and snippets.

@serradura
Created November 11, 2021 23:30
Show Gist options
  • Save serradura/85f2bf1d771a1ba09ca74c191c534b5e to your computer and use it in GitHub Desktop.
Save serradura/85f2bf1d771a1ba09ca74c191c534b5e to your computer and use it in GitHub Desktop.
Exemplo de como fazer um flow condicional com u-case + como ter steps mais claros ao importar constantes de outro namespace
require_relative 'a_ext'
module Goals
class BuildMonthDistributionFlow < Micro::Case
include Constants[
:SumGoalsDaysAtPeriod, :ValidateDailyDistribution, :ValidatePeriodDistribution,
:BuildPeriodsAndDaysByDailyWeight, :BuildPeriodsAndDaysByPeriodWeight
].from(Goals::Cases::Monthly)
attributes :periods, :goal
def call!
return Success result: { goal: goal } unless goal.tipo_calculo == 'mes'
call(ValidatePeriodDistribution, goal: goal, periods: periods)
.then(ValidateDailyDistribution)
.then(BuildPeriodsAndDaysByPeriodWeight)
.then(BuildPeriodsAndDaysByDailyWeight)
.then(SumGoalsDaysAtPeriod)
.then_expose(:goal)
end
end
end
class Micro::Case::Result
def then_expose(*keys)
return self if failure?
raise ArgumentError, 'wrong number of arguments (expected at least 1)' if keys.empty?
type, keys_to_expose =
keys.size == 1 && keys[0].is_a?(::Hash) ? keys[0].to_a[0] : [:data_exposed, keys]
data_to_expose = keys_to_expose.zip(data.merge(@__accessible_attributes).fetch_values(*keys_to_expose)).to_h
__set__(true, data_to_expose, type, use_case)
end
alias then_return then_expose
end
module Constants
class Importer
def initialize(const_names)
@const_names = const_names
end
def from(module_or_class)
Module.new.tap do |mod|
mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
class << self
attr_accessor :from, :const_names
end
def self.included(to)
consts = const_names.map { |name| from.const_get(name, false) }
const_names.zip(consts).each { |(name, const)| to.const_set(name, const) }
end
RUBY
mod.from = module_or_class
mod.const_names = @const_names
end
end
end
def self.[](*names)
Importer.new(names)
end
end
module Goals
class BuildMonthDistributionFlow < Micro::Case
attributes :periods, :goal
def call!
return Success result: { goal: goal } unless goal.tipo_calculo == 'mes'
call(Goals::Cases::Monthly::ValidatePeriodDistribution, goal: goal, periods: periods)
.then(Goals::Cases::Monthly::ValidateDailyDistribution)
.then(Goals::Cases::Monthly::BuildPeriodsAndDaysByPeriodWeight)
.then(Goals::Cases::Monthly::BuildPeriodsAndDaysByDailyWeight)
.then(Goals::Cases::Monthly::SumGoalsDaysAtPeriod)
.then_expose(:goal)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment