Rails 6 not auto-loading class properly in development (zeitwerk mode)

Viewed 2173

My understanding is that Rails is able to auto-load classes properly named within the app folder, by default.

It's not happening for me, so I want to see if you can find an obvious issue with my code.

My folders/files:

app
   blueprints
      concerns
         ingredient_blueprint_concern.rb
      liqueur_blueprint.rb
   controllers
   models
   ...
#app/blueprints/concerns/ingredient_blueprint_concern.rb

module Concerns
  module IngredientBlueprintConcern
    extend ActiveSupport::Concern

    included do
      attributes :name
    end
  end
end

# app/blueprints/liqueur_blueprint.rb

class LiqueurBlueprint < BaseBlueprint
  include ::Concerns::IngredientBlueprintConcern

  # ...
end

rails console:

> Concerns
=> NameError (uninitialized constant Concerns
   Did you mean?  Concurrent):

It seems related to the new Rails 6 zeitwerk mode. If I go back the the classic mode (with the code below), it seems to work fine:

# application.rb
config.autoloader = :classic
2 Answers

https://github.com/rails/rails/issues/36054

Ok so turns out that the concerns folders are actually in the rails load paths, so it means they shouldnt be namespaced, the same way a class is app/models isn't in the Models namespace.

The fact that they were working in Rails 5 was some sort of side-effect that I wont get into here, but you can read about in the link above.

I wonder if we can get an answer on this ...

# app/foo/bar.rb

module Foo
  class Bar
    def output
      'worked'
    end
  end
end

irb(main):001:0> Foo
NameError (uninitialized constant Foo)

irb(main):002:0> Bar
Zeitwerk::NameError (expected file /Users/simon/Projects/tmp/test_module/app/foo/bar.rb to define constant Bar, but didn't)

irb(main):003:0> Foo
=> Foo

But

irb(main):007:0> ActiveSupport::Dependencies.autoload_paths.include?("/Users/simon/Projects/tmp/test_module/app/foo")
=> true

And why does it work if I call Bar first and after Foo? Autoloading issue?

Edit (Aug 1, 2020)

changing the file path to app/foo/foo/bar.rb made it work. For now a workaround for me.

Related