Rails 6 Autoload Not Finding Class

Viewed 3134

I'm attempting to upgrade from Rails 5 to 6. I did the upgrade steps including adding this:

# config/application.rb
config.load_defaults 6.0

I have this class:

# lib/notification/auto_thank.rb
module Notification
  class AutoThank
    def perform
      # stuff
    end
  end
end

Which is used in a task:

namespace :notify do
  task auto_thank: :environment do
    Notification::AutoThank.new.perform
  end
end

When I do puts config.autoload_paths, it's listed, so I expect it to autoload:

/my/app/path/lib/notification/auto_thank.rb

But when I run the task I get an error:

NameError: uninitialized constant Notification

It gets stranger. When I add a require to the task:

task auto_thank: :environment do
  require '/my/app/path/lib/notification/auto_thank.rb'
  Notification::AutoThank.new.perform
end

I get a different error:

NameError: expected file /my/app/path/lib/notification/auto_thank.rb to define constant AutoThank, but didn't

What am I missing?

1 Answers

If you can, locate your auto-loading code in app/. As of Rails 6 everything in there will be automatically part of the auto-load path. Rails 5 was more selective.

In this case call it: app/notifications/notification/auto_thank.rb

The first part of the path is ignored. The second (optional) part is the namespace.

Note that to get this to show up in the auto-loader you may need to stop the Spring process with spring stop. This must be done any time you introduce a new app/... path.

Related