Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alainravet/042f25054f0e2bbc6956 to your computer and use it in GitHub Desktop.
Save alainravet/042f25054f0e2bbc6956 to your computer and use it in GitHub Desktop.
Service Object with on_success and on_failure blocks
#----------------------
# Library code:
class BasicServiceObject
attr_reader :object
def initialize(o)
@object = o
end
end
class ServiceObjectWithHooks < BasicServiceObject
def perform
@_perform_called = true
@_success = yield
self
end
def on_success
ensure_perform_was_called
yield if @_success
self
end
def on_failure
ensure_perform_was_called
yield unless @_success
self
end
private
def ensure_perform_was_called
return if @_perform_called
fail "
the service object action was not wrapped in a `perform` block.
Example :
class FooService < ServiceObjectWithHooks
def foo
perform do
result = object.foo
Logger.log('object was fooed')
result
end
end
end
"
end
end
#----------------------
# how to define a new service:
class SaviourService < ServiceObjectWithHooks
def save_and_do_stuff
perform do # MUST wrap in a `perform` block!
object.save # <-- your code
end
end
end
#----------------------
# how to use the service:
class Foo
def save
result = (random_boolean = [true, false].sample)
end
end
# way 1:
SaviourService.new(Foo.new)
.save_and_do_stuff
.on_success do
puts 'SUCCESS'
end
.on_failure do
puts 'FAILURE'
end
# way 2:
operation = SaviourService.new(Foo.new).save_and_do_stuff
# ...
operation.on_success do
puts 'SUCCESS'
end
# ...
operation.on_failure do
puts 'FAILURE'
end
class ServiceObjectWithHooks
attr_reader :object
def initialize(o)
@object = o
end
def on_success
fail '@success was not defined' unless instance_variable_defined?(:@success)
yield if @success
self
end
def on_failure
fail '@success was not defined' unless instance_variable_defined?(:@success)
yield unless @success
self
end
end
#-----------
class Saviour < ServiceObjectWithHooks
def save
@success = object.save
self
end
end
class Foo
def save
result = random_boolean = [true, false].sample
end
end
#-----------
Saviour.new(Foo.new)
.save
.on_success do puts 'SUCCESS' end
.on_failure do puts 'FAILURE' end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment