Skip to content

Instantly share code, notes, and snippets.

@ejlangev
Created June 19, 2014 21:07
Show Gist options
  • Save ejlangev/9b3f4d779d6512221c95 to your computer and use it in GitHub Desktop.
Save ejlangev/9b3f4d779d6512221c95 to your computer and use it in GitHub Desktop.
Rails Responder
class CreditCardController < ApplicationController
def create
creator = CreditCardCreator.call(params)
# creator.respond_to?(:errors) => true
# creator.errors => [] (by default)
# when something goes wrong: creator.errors => ['Terrible Error']
respond_with(creator)
end
end
# Also sets the proper responses
# Success looks like { expiration_date: '2014-10-10', ... }
# Errors look like { errors: ['Terrible Error'] }
class Grouper::ServiceObject
def errors
@errors ||= []
end
end
class CreditCardCreator < Grouper::ServiceObject
def call(params)
card = CreditCard.new(params)
unless card.save
@errors = card.errors
return false
end
...
response = Stripe.create_card(data)
unless response.success?
self.errors << response.error_message
return false
end
return true
end
end
@brett-richardson
Copy link

I like this, but this would be responding with true/false no?

@ejlangev
Copy link
Author

I was assuming CreditCardCreator.call(params) returned an instance of CreditCardCreator

@mikekelly
Copy link

all this really does is shift code around and introduce more indirection. It also requires/encourages service objects with mutable state.

not a fan of respond_with, either - it's yet more indirection that relies on opaque conventions about object state to magically produce the various HTTP responses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment