Advanced Rails - Building Industrial-Strength Web Apps in Record Time

(Tuis.) #1
Metaprogramming Techniques | 35

module ActiveMerchant
module Billing
module Integrations
module ActionViewHelper
def payment_service_for(order, account, options = {}, &proc)
...
end
end
end
end
end

Then, in the plugin’sinit.rb script, the module is included inActionView::Base:


require 'active_merchant/billing/integrations/action_view_helper'
ActionView::Base.send(:include,
ActiveMerchant::Billing::Integrations::ActionViewHelper)

It certainly would be simpler in code to directly openActionView::Baseand add the
method, but this has the advantage of modularity. All Active Merchant code is con-
tained within theActiveMerchant module.


There is one caveat to this approach. Because any included modules are searched for
methods after the class’s own methods are searched, you cannot directly overwrite a
class’s methods by including a module:


module M
def test_method
"Test from M"
end
end

class C
def test_method
"Test from C"
end
end

C.send(:include, M)
C.new.test_method # => "Test from C"

Instead, you should create a new name in the module and usealias_method_chain:


module M
def test_method_with_module
"Test from M"
end
end

class C
def test_method
"Test from C"
end
end
Free download pdf