如何通过 prepend 猴子修补 ActionView 模块?
How to monkey-patch an ActionView module via prepend?
如果您在 class SomeClass
中包含模块 Foo
,则在该模块前面加上另一个模块 Bar
,[=15= 中的任何方法覆盖] 不会在 SomeClass
生效。示例:
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
已经被包含(在它应该被包含的任何地方)因此前置似乎没有生效。有人知道解决这个问题的方法吗?
在不回答你关于模块前置的具体问题的情况下,这里是另一种方式:
由于 Rails 中的助手是全局的,您可以简单地创建自己的助手并覆盖 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
不如创建初始化程序,因为我不需要在帮助程序模块中对继承链进行硬编码。
如果您在 class SomeClass
中包含模块 Foo
,则在该模块前面加上另一个模块 Bar
,[=15= 中的任何方法覆盖] 不会在 SomeClass
生效。示例:
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
已经被包含(在它应该被包含的任何地方)因此前置似乎没有生效。有人知道解决这个问题的方法吗?
在不回答你关于模块前置的具体问题的情况下,这里是另一种方式:
由于 Rails 中的助手是全局的,您可以简单地创建自己的助手并覆盖 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
不如创建初始化程序,因为我不需要在帮助程序模块中对继承链进行硬编码。