[Question] `Rails.autoloaders.main` is `nil` in initializer (undefined method `push_dir' for nil:NilClass)
adrianthedev opened this issue · 4 comments
This is not an issue with zeitwerk per-se, but this is the best place I came up to ask this question because I know that the people here are knoledgeable about these things.
I apologize if this is innapropiate.
I made and published https://github.com/avo-hq/avo, a Rails engine packaged as a gem.
In my engine.rb
file I'm pushing a few directories to the main autoloader using this code:
module Avo
class Engine < ::Rails::Engine
isolate_namespace Avo
initializer "avo.autoload" do |app|
[
["app", "avo", "fields"],
["app", "avo", "filters"],
["app", "avo", "actions"],
["app", "avo", "resources"],
["app", "avo", "dashboards"],
["app", "avo", "cards"],
["app", "avo", "resource_tools"]
].each do |path_params|
path = Rails.root.join(*path_params)
if File.directory? path.to_s
Rails.autoloaders.main.push_dir path.to_s
end
end
end
end
end
It does the job and finds the files it needs to work with.
I have this small percentage of users that run into this issue where the Rails.autoloaders.main
object is nil
and the app fails to boot up.
My question is, what could cause Rails.autoloaders.main
to be nil
on initialization? Only two users reported that and I haven't been able to come up with a reason on why it's happening.
Thank you!
I suspect those applications are using the classic
autoloader, in which case the Zeitwerk-based autoloaders are not instantiated (this is deliberate).
In your case, the portable solution is to use the Rails API, which works in both autoloading modes:
ActiveSupport::Dependencies.autoload_paths += app_avo_directories
You can delete the if
, because Rails does it for you.
Got it! I'm going back to confirm that with the app users.
Thank you for your response!
Closing until I confirm that.
Confirmed that their app was not using zeitwerk
. We couldn't find any config.autoloader
reference because it was a Rails 5 app.
The fix was adding config.load_defaults 6.1
to config/production.rb
.