rails / mission_control-jobs

Dashboard and Active Job extensions to operate and troubleshoot background jobs
MIT License
611 stars 71 forks source link

Existing inflection for "UI" breaks UiHelper #129

Closed christopher-b closed 3 months ago

christopher-b commented 5 months ago

My app includes an acronym inflection for "UI", used for my own ViewComponents:

inflect.acronym "UI"

When I try to load the jobs dashboard, I get an error:

uninitialized constant MissionControl::Jobs::ApplicationHelper::UiHelper
app/helpers/mission_control/jobs/application_helper.rb:6:in `<module:ApplicationHelper>' 

If I remove the inflection, the error goes away.

Strangely, the error only occurs the first time I try to load /jobs after booting the application. If I reload the page, I get a different error.

Is there anything that can be done to resolve this, other than removing my inflection and renaming my components? Is there someway to override the inflection in the engine? Thanks!

gjtorikian commented 3 months ago

Based on this SO answer, I came up with the following to work around this in my own app:

# List of file glob patterns and their corresponding camelized class names
OVERRIDES = {
  "**gems/mission_control-jobs-*/app/helpers/mission_control/jobs/ui_helper.rb" => "UiHelper",
}.freeze

# Override the default Zeitwerk inflector to use the overrides
Rails.autoloaders.each do |autoloader|
  autoloader.inflector = Class.new(Zeitwerk::Inflector) do
    define_method(:camelize) do |basename, abspath|
      # Check if the file path matches any of the overrides
      OVERRIDES.each do |glob_pattern, normalized|
        next unless File.fnmatch?(glob_pattern, abspath)

        # Return the hard-coded normalized class name
        return normalized
      end
      # For all other files, use the default ActiveSupport::Inflector.camelize
      basename.camelize
    end
  end.new
end

It ain't pretty, but it works!