NameError: неинициализированная константа #‹Class:0x00007fadd32ea580›::Searchable

При отладке несвязанной проблемы в rspec я сталкиваюсь с проблемами с постоянной загрузкой. Настройка выглядит следующим образом:

# 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

Я получил следующую ошибку во время отладки. NameError: uninitialized constant #<Class:0x00007fadd32ea580>::Searchable Изменение имени на Foos::Searchable с соответствующим перемещением папки действительно решает проблему, но я хотел бы понять, что на самом деле происходит.

Рельсы 6.0.3.1 Руби 2.6.6


person zach    schedule 03.06.2020    source источник


Ответы (3)


Помимо использования << вместо <, вы стали жертвой очень распространенной проблемы из-за неправильного использования оператора разрешения области видимости ::. Его не следует использовать при объявлении вложенных классов или модулей, так как это приводит к неправильному вложению модулей и приведет к отсутствующей постоянной ошибке, если модуль, в который вы вкладываете, уже загружен.

Вы всегда должны явно объявлять вложенные модули/классы:

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

Причина, по которой эта проблема всплывает повсюду после перехода на Rails 6, заключается в том, что старый классический автозагрузчик перегружал Module#const_missing и игнорировал эти ошибки, как если бы он автоматически загружал Foo.

Zeitwork, который заменяет классический автозагрузчик, вместо этого использует Module#autoload, который является относительно новым дополнением к Ruby и намного менее хакерским.

person max    schedule 04.06.2020

Оказывается, это вызвано несовместимостью с Byebug. Byebug останавливает события, которые Zeitwerk использует для автозагрузки, чтобы запустить сеанс отладки. Проблема описана здесь.

<< было опечаткой и не приводило к этой ошибке.

person zach    schedule 08.06.2020

Возможно, вам следует заменить ‹‹ на ‹. Вы наследуете, а не перенаправляете

class Foo < ApplicationRecord
  include Foo::Searchable
end
person Vitalii    schedule 04.06.2020