1

While debugging an unrelated issue in rspec, I'm coming across issues with constant loading. The setup is as follows:

# app/models/foo.rb

class Foo << ApplicationRecord
  include Foo::Searchable
end
# app/models/foo/searchable.rb

module Foo::Searchable
  extend ActiveSupport::Concern

  included do
    #yada yada
  end
end

I received the following error while debugging. NameError: uninitialized constant #<Class:0x00007fadd32ea580>::Searchable Changing the naming to Foos::Searchable with corresponding folder move does fix the issue but I would like to understand what is actually happening.

Rails 6.0.3.1 Ruby 2.6.6

vinibrsl
  • 6,563
  • 4
  • 31
  • 44
zach
  • 319
  • 1
  • 11

3 Answers3

1

As well as using << instead of < you have fallen victim to really common issue due to missusing the scope resolution operator ::. It should not be used when declaring nested classes or modules as it leads to the wrong module nesting and will lead to a missing constant error unless the module which you are nesting in is already loaded.

You should always explitly declare nested modules/classes:

class Foo < ApplicationRecord
  module Searchable
    extend ActiveSupport::Concern
    included do
      #yada yada
    end
  end
end

The reason this issue is popping up everywhere after the transition to Rails 6 is that the old classic autoloader overloaded Module#const_missing and glassed over these bugs as it would autoload Foo.

Zeitwork which replaces the classic autoloader instead uses Module#autoload which is a relatively new addition to Ruby and a lot less hacky.

max
  • 96,212
  • 14
  • 104
  • 165
1

This turns out to be caused by incompatibility with Byebug. Byebug stops the events Zeitwerk uses for autoloading to fire off in a debugging session. The issue is described here.

The << was a typo and would not result in that error.

zach
  • 319
  • 1
  • 11
0

Perhaps you should replace << with <. You inherit, not redirect

class Foo < ApplicationRecord
  include Foo::Searchable
end
Vitalii
  • 113
  • 1
  • 1
  • 11