I've got a gem with a class that dynamically includes modules. I need to override all methods in those modules to insert some additional logic (for metrics tracking)
Example class:
module MyAPI
class Client
# This dynamically requires a bunch of modules
Dir[File.dirname(__FILE__) + '/client/*.rb'].each do |file|
require file
include const_get(File.basename(file).gsub('.rb','').split('_').map(&:capitalize).join('').to_s)
end
end
end
One of these modules might look like this:
module MyAPI
class Client
module Companies
def get_company(company_id, params = {})
puts "original method"
end
end
end
end
I need to monkey patch this in my application. I have added a new file /config/initializers/monkey_patches/my_api.rb
module MyAPI
class Client
module MonkeyPatchCompanies
def get_company(company_id, params = {})
puts 'Monkey Patched'
super
end
end
module Companies
include MonkeyPatchCompanies
end
end
end
I have tried all sorts of things like the above to add some functionality to all of the methods in the included modules.
Nothing I have tried has been successful. I get something like:
NoMethodError (undefined method `include?' for nil:NilClass)
What is the best way to monkey patch something like this?
EDIT:
I was able to solve this by first aliasing the the original method, then by calling the aliased original in my overridden method.
module_eval do
alias_method :get_company_old, :get_company
define_method :get_company do |*args|
# My new code here
send :get_company_old, *args
end
The problem is that super
in this context does not work. This solved the issue for me.