Last active
December 25, 2015 23:19
-
-
Save kerinin/7056008 to your computer and use it in GitHub Desktop.
Shower-thoughts on response objects
This file contains hidden or 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 ResponseObject | |
def initialize | |
@handlers = Hash.new { [] } | |
yield self | |
end | |
def do(state, *args) | |
@state = state | |
@args = args | |
end | |
def on(state, &response) | |
@handlers[state] << response | |
end | |
def respond(handler) | |
handler.call(self) | |
if @state.nil? | |
raise IndeterminateStateException, "Response state was not declared" | |
elsif @handlers.has_key?(@state) | |
@handlers[@state].call(@args) | |
else | |
raise UnhandledStateException, "State #{@state} has no defined handler" | |
end | |
end | |
end | |
class Foos | |
def with_new_foo(attributes={}, &block) | |
ResponseObject.new do |r| | |
r.do(:success, create_foo(attributes)) | |
# I'm not sure that do..end defines a rescue scope, but it's prettier, so I'll assume it does | |
rescue FooExisits | |
r.do(:duplicate, find_foo(attributes)) | |
rescue ValidationError => e | |
$statsd.increment("foo_validation_failures") | |
r.do(:validation_failure, e) | |
end.respond(block) | |
end | |
end | |
class FooController | |
def create | |
Foos.with_new_foo(params[:foo]) do |r| | |
r.on(:success) do |foo| | |
render_foo(foo) | |
end | |
r.on(:duplicate) do |foo| | |
render_foo(foo) | |
end | |
r.on(:validation_failure) do |e| | |
render_validation_failure(e) | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment