如何覆盖从 gem 加载的控制器辅助方法

How to override controller helper method loaded from a gem

我有一种情况,我试图避免更改数百个 rails 视图,这些视图调用辅助方法(page_title)从 gem。我想创建一个具有完全相同名称 (page_title) 的助手 。然后,在这个新的 page_title 助手中,我想检查一个条件;如果条件是 true,我想执行一些逻辑,如果它是 false我想执行 page_title 从 gem.

加载的助手

在我们看来,我们正在调用 page_title(从 gem 加载):

<%= page_title domain: "Leasing", page: "Guest Cards" %>

gem 加载此模块...

module OsmUiHelper
  ...
  def page_title(options = {})
    ...
  end
  ...
end

...像这样...

module OsmUi
  module Rails
    class Engine < ::Rails::Engine
      ...
      config.to_prepare do
        ApplicationController.helper(OsmUiHelper)
      end
    ...
  end
end

我试过各种体操,试图让它发挥作用,但都失败了。我最近的尝试是尝试将 gem 中的 page_title 方法别名为 old_page_title ,希望当我的 page_title 助手(见下文)被加载时,它会覆盖gem 中的 page_title 一切都很好,但是 gem 中的旧 page_title 被调用:

# /controllers/helper/page_title_helper.rb
module Controllers
  module PageTitleHelper
    def page_title(options = {})
      company_id = settings ? settings.company_id : 0
      if Feature.on?('omnibar_enabled', company_id)
        # Use my page_title logic here
      else
        # Use the gem page_title aliased as old_page_title (see below)
        old_page_title(options)
      end
    end
  end
end

# /rails/lib/osm_ui_helper_patch.rb
require 'osm_ui_helper'

module OsmUiHelper
  alias_method :old_page_title, :page_title
end

我怎样才能让它工作?有没有可能直接在 ApplicationController.helpers 中操纵助手?我已经无计可施了。

提前致谢。

解决方案

这解决了我的问题。简单:

# /rails/app/helpers/controllers/page_title_helper.rb

module Controllers
  module PageTitleHelper
    include OsmUiHelper

    alias old_page_title page_title

    # rubocop:disable Style/OptionHash
    def page_title(options = {})
      company_id = settings ? settings.company_id : 0
      if Feature.on?('omnibar_enabled', company_id)
        # New logic here
      else
        # Use the old page_title in the gem
        old_page_title(options)
      end
    end
    # rubocop:enable Style/OptionHash
  end
end

这解决了我的问题。简单:

# /rails/app/helpers/controllers/page_title_helper.rb

module Controllers
  module PageTitleHelper
    include OsmUiHelper

    alias old_page_title page_title

    # rubocop:disable Style/OptionHash
    def page_title(options = {})
      company_id = settings ? settings.company_id : 0
      if Feature.on?('omnibar_enabled', company_id)
        # New logic here
      else
        # Use the old page_title in the gem
        old_page_title(options)
      end
    end
    # rubocop:enable Style/OptionHash
  end
end