2016-11-01 31 views
2

如果在類別SomeClass中包含模塊Foo,則將該模塊預先加入另一個模塊BarBar中的任何方法覆蓋將不會在SomeClass中生效。例如:如何通過prepend對ActionView模塊進行猴子修補?

module Foo 
    def some_method 
    puts 'In Foo' 
    end 
end 

class SomeClass 
    include Foo 
end 

SomeClass.new.some_method # => 'In Foo' 

module Bar 
    def some_method 
    puts 'In Bar' 
    super 
    end 
end 

Foo.prepend Bar 

Foo.ancestors # => [Bar, Foo] 

SomeClass.new.some_method # => 'In Foo' 

class AnotherClass 
    include Foo 
end 

AnotherClass.new.some_method # => 
# 'In Bar' 
# 'In Foo' 

我想猴子補丁的的ActionView輔助方法,方式如下:

lib/core_extensions/action_view/helpers/url_helper/secure_link_to

module CoreExtensions 
    module ActionView 
    module Helpers 
     module UrlHelper 
     module SecureLinkTo 
      def link_to(name = nil, options = nil, html_options = nil, &block) 
      html_options ||= {} 
      if html_options[:target].present? 
       html_options[:rel] = 'noopener noreferrer' 
      end 

      super(name, options, html_options, &block) 
      end 
     end 
     end 
    end 
    end 
end 

,然後在初始化:

ActionView::Helpers::UrlHelper.prepend CoreExtensions::ActionView::Helpers::UrlHelper::SecureLinkTo 

但是,這似乎並不奏效。我的假設 - 在初始化器執行時,ActionView::Helpers::UrlHelper已經包含在內(無論它應該包含在哪裏),因此預計似乎不會生效。有人知道這個解決方案嗎?

+0

爲什麼不重新打開'ActionView :: Helpers :: UrlHelper'並在那裏定義方法? (除此之外,你的方法感覺更清潔) –

+0

好吧,正如你所說 - 我想以一種乾淨的方式做到這一點。我遵循這個:http://nofail.de/2014/06/monkey-patching-rails/和這篇文章推薦'prepend'作爲最好的解決方案。 –

回答

1

沒有回答您的具體問題有關模塊前插,這裏將是另一種方式:

由於Rails的helper是全球性的,你可以簡單地創建了自己的助手與覆蓋了link_to方法。

module LinkHelper 
    def link_to(name = nil, options = nil, html_options = nil, &block) 
    html_options ||= {} 
    if html_options[:target].present? 
     html_options[:rel] = 'noopener noreferrer' 
    end 

    super(name, options, html_options, &block) 
    end 
end 

不知怎的,這似乎比創建一個初始化,因爲我不需要硬編碼的傳承鏈條助手模塊中少hacky

+0

謝謝你的激光,馬格努斯。我在哪裏放這個文件? –

+0

@AlexPopov這是一個普通的舊幫手模塊。你把它放在'app/helpers'中。 – Magnuss

+0

僅供參考:http://stackoverflow.com/questions/10471535/override-rails-helpers-with-access-to-original –