2016-11-01 7 views
2

모듈 Foo을 클래스 SomeClass에 포함시킨 다음 해당 모듈 앞에 다른 모듈 Bar을 추가하면 Bar 내부의 모든 메서드 덮어 쓰기가 SomeClass에서 적용되지 않습니다. 예 : 초기화에 다음prepend를 통해 ActionView 모듈을 원숭이 패치하는 방법은 무엇입니까?

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 

과 :

lib/core_extensions/action_view/helpers/url_helper/secure_link_to에서 :

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 도우미 방법을 다음과 같은 방법을 원숭이 패치

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

그러나 이것은 작동하지 않습니다. 내 가정 - 이니셜 라이저가 실행될 때까지 ActionView::Helpers::UrlHelper이 이미 포함되었으므로 (포함될 예정 임) 따라서 prepending이 적용되지 않는 것 같습니다. 아무도 이것에 대한 해결책을 알고 있습니까? 레일에서 헬퍼 글로벌이기 때문에, 당신은 단순히 재정의 link_to 방법으로 자신의 도우미를 만들 수 있습니다

: 또 다른 방법이 될 것입니다 여기에, 모듈 앞에 추가에 대한 특정 질문에 대답하지 않고

+0

왜'ActionView :: Helpers :: UrlHelper'를 다시 열고 거기에 메서드를 정의하지 않았습니까? (당신의 접근 방식이 다소 더 깨끗하다고 ​​느껴진다는 점을 제외하고) –

+0

정확히 말하면, 나는 깨끗한 방법으로 그것을하고 싶습니다. 나는 이것을 따르고있다. http://nofail.de/2014/06/monkey-patching-rails/이 기사는 최상의 해결책으로'prepend'를 추천한다. –

답변

1

.

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

감사합니다, Magnuss. 이 파일은 어디에 두어야합니까? –

+0

@AlexPopov 일반 오래된 도우미 모듈입니다. 당신은'app/helpers'에 넣었습니다. – Magnuss

+0

참조 : http://stackoverflow.com/questions/10471535/override-rails-helpers-with-access-to-original –