모듈 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
방법으로 자신의 도우미를 만들 수 있습니다
: 또 다른 방법이 될 것입니다 여기에, 모듈 앞에 추가에 대한 특정 질문에 대답하지 않고
왜'ActionView :: Helpers :: UrlHelper'를 다시 열고 거기에 메서드를 정의하지 않았습니까? (당신의 접근 방식이 다소 더 깨끗하다고 느껴진다는 점을 제외하고) –
정확히 말하면, 나는 깨끗한 방법으로 그것을하고 싶습니다. 나는 이것을 따르고있다. http://nofail.de/2014/06/monkey-patching-rails/이 기사는 최상의 해결책으로'prepend'를 추천한다. –