ruby-on-rails - 如何通过 prepend 猴子修补 ActionView 模块?

标签 ruby-on-rails ruby monkeypatching prepend

如果您在类 SomeClass 中包含一个模块 Foo,则在该模块前面加上另一个模块 BarBar 中的任何方法覆盖 Bar不会在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,因为我不需要在辅助模块中对继承链进行硬编码。

关于ruby-on-rails - 如何通过 prepend 猴子修补 ActionView 模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40356669/

相关文章:

django - Django模板中的正确缩进(没有猴子补丁)?

ruby-on-rails - Rails Heroku “The page you were looking for doesn’ t 存在。”部署后

ruby-on-rails - 用于静态网站的 ruby​​ on rails

ruby - 如何创建支持 Ruby 的 shell 命令?

ruby - 如何映射嵌套数组

python - 使用 forbiddenfruit 使 int 可迭代

ruby-on-rails - Rake 与我的数据库不同步

ruby-on-rails - 在 Rails 中进行 cometd /长轮询的最佳方法是什么?

javascript - map 在第一次打开页面时不加载,重新加载后即可工作

Python:强制每个导入重新加载