Skip to content

Instantly share code, notes, and snippets.

@pduey
Last active October 13, 2015 08:58
Show Gist options
  • Save pduey/4171390 to your computer and use it in GitHub Desktop.
Save pduey/4171390 to your computer and use it in GitHub Desktop.
Overwrite ruby method in Rails development only, calls original method with *args, &block
# I needed to overwrite (not override) the Savon::Client.request method in my development
# environment only, and only for 1 type of request that happens to hit a host I can access
# only in production. For all other requests, it should invoke the original Savon::Client.request.
# I found it a little tricky since it takes optional args and a block. Here's what worked, which
# I learned from these two stackoverflow answers
# http://stackoverflow.com/questions/4470108/when-monkey-patching-a-method-can-you-call-the-overridden-method-from-the-new-i
# http://stackoverflow.com/questions/89650/how-do-you-pass-arguments-to-define-method
# It's maybe similar to how rspec implements the stub method?
Savon::Client.class_eval do
if Rails.env.development?
original_request = instance_method( :request )
define_method( :request ) do |*args, &block|
Rails.logger.info "Invoking patched version of #{self.class.name}.request for development"
return :my_response_hash => { :top_level_node => { :result => { :error_code => "0", :error_description => "Success" }, :my_return_value => "A Return Value" } } if args[0] == "Stub Request"
Rails.logger.info "Action specified (#{args[0]}) should work in development, invoking original #{self.class.name}.request"
original_request.bind(self).call(args, &block)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment