Last active
November 8, 2019 19:02
-
-
Save cainlevy/0600c91c638acbf3573688ad5d3141d6 to your computer and use it in GitHub Desktop.
Simple base class for service objects that implement 1) an initializer and 2) a perform method that returns a Promise
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
# Service objects are classes that inherit from this base and implement two instance methods: | |
# * initialize(*args, **params) => void | |
# * perform() => Promise | |
class ServiceBase | |
include ActiveModel::Validations | |
# invokes the service and returns a Promise | |
def self.perform(*args, **params) | |
klass = params.any? ? new(*args, **params) : new(*args) | |
klass.perform_in_transaction | |
end | |
# invokes the service. returns a value on success, and raises an exception on failure. | |
def self.perform!(*args, **params) | |
perform(*args, **params).unbox | |
end | |
# must be implemented by inheriting class to return a Promise | |
def perform | |
raise MethodNotImplemented | |
end | |
def perform_in_transaction | |
instrument do | |
transaction do | |
perform | |
end | |
end | |
end | |
private def instrument | |
# ... New Relic or Datadog or STATSD or what have you | |
end | |
private def transaction | |
result = nil | |
ActiveRecord::Base.transaction do | |
result = yield | |
result.rescue { raise ActiveRecord::Rollback } | |
end | |
result | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment