gangelo
gangelo

Reputation: 3182

How to override controller helper method loaded from a gem

I have a situation where I am trying to avoid changing hundreds of rails views that call a helper method (page_title) loaded from a gem. I want to create a helper with the exact same name (page_title). Then, within this new page_title helper, I want to check a condition; if the condition is true, I want to perform some logic and if it's false, I want to execute the page_title helper loaded from the gem.

In our views, we're calling page_title (loaded from a gem):

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

The gem loads this module...

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

...like this...

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

I've tried all sorts of gymnastics trying to get this to work and all have failed. My latest attempt was trying to alias the page_title method in the gem to old_page_title in the hope that when my page_title helper (see below) is loaded, it would override page_title in the gem and all would be good, but the old page_title in the gem is being called:

# /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

How can I get this to work? Is there anyway to manipulate the helpers directly in ApplicationController.helpers perhaps? I'm at my wits end.

Thanks in advance.

SOLUTION

This solved my issue. Simple:

# /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

Upvotes: 3

Views: 839

Answers (1)

gangelo
gangelo

Reputation: 3182

This solved my issue. Simple:

# /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

Upvotes: 3

Related Questions