Skip to content

Instantly share code, notes, and snippets.

@apneadiving
Last active August 29, 2015 14:07
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apneadiving/f1de3517a727e7596564 to your computer and use it in GitHub Desktop.
Save apneadiving/f1de3517a727e7596564 to your computer and use it in GitHub Desktop.
The before is some standard code, `with_waterfall` presents another way to write it (fully chainable)
# In controller
result = TaxCalculator.new(order).call
if result[:success]
render json: { value: result[:value] }
else
render json: { errors: result[:errors] }, status: 422
end
# The service
class TaxCalculator
attr_reader :order
include ::ActiveModel::Validations
def initialize(order)
@order = order
end
def call
return set_error(:tax_ranges, 'The tax ranges were not found') unless tax_ranges
return set_error(:tax_percentage, 'The tax percentage was not found') unless tax_percentage
{ success: true, value: calculate}
end
def calculate
(order.total * (tax_percentage/100)).round(2)
end
def tax_percentage
@tax_percentage ||= tax_ranges.for_total(order.total)
end
def tax_ranges
@tax_ranges ||= TaxRange.for_region(order.region)
end
def set_error(key, val)
errors.add(key, val)
{ success: false, errors: errors}
end
end
Repository here: https://github.com/apneadiving/waterfall
# In controller
Wf.new
.chain (tax: :tax_result) { TaxCalculator.new(order) }
.chain {|outflow| render json: { value: outflow[:tax] } }
.on_dam {|error_pool| render json: { errors: error_pool}, status: 422 }
# The service
class TaxCalculator
include WaterFall
attr_reader :order
def initialize(order)
@order = order
end
def call
self
.when_falsy { tax_ranges }
.dam { 'The tax percentage was not found' }
.when_falsy { tax_percentage }
.dam { 'The tax ranges were not found' }
.chain(:tax_result) { calculate }
end
def calculate
(order.total * (tax_percentage/100)).round(2)
end
def tax_percentage
@tax_percentage ||= tax_ranges.for_total(order.total)
end
def tax_ranges
@tax_ranges ||= TaxRange.for_region(order.region)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment