Вероятно, это связано с загрузчиком рельсов. При этом:
module Foo
class Bar
end
end
А затем, пытаясь использовать Foo::Bar
, автозагрузчик сначала пытается найти app/models/foo/bar.rb
. Файл загружен, и здесь определено module Foo
(хотя это и модуль, содержащий только Bar
), поэтому автозагрузчик никогда не пытается загрузить app/models/foo.rb
.
Это должно происходить только в режиме разработки, так как в рабочем режиме все ваши файлы require
d при запуске.
Есть два обходных пути AFAIK:
Чит автозагрузчик
объявите свой класс с помощью class Foo::Bar
, чтобы автозагрузчик разрешил постоянный поиск для Foo
.
Это имеет раздражающий побочный эффект, что постоянный поиск внутри Bar
НЕ будет ограничен внутри Foo
, например:
# app/models/foo.rb
module Foo
BAZ = "baz"
end
# app/models/foo/bar.rb
class Foo::Bar
def baz
BAZ
end
end
здесь, Foo::Bar.new.baz
потерпит неудачу, если вы не ссылаетесь на константу, используя Foo::BAZ
. Например, это может привести к путанице при определении ассоциаций ActiveRecord.
Требуется модуль
с использованием require_dependency
:
require_dependency 'foo'
module Foo
class Bar
end
end
Это ИМХО правильное решение, так как оно не нарушает постоянный поиск, но это также немного раздражает, так как вы должны добавить оператор require поверх каждого файла пространства имен.
Примечание:
Эта ошибка, похоже, была устранена в rails 4. Я много раз использовал второй обходной путь, когда на rails 3, но я пытался воспроизвести ошибку в rails 4, и она больше не отображается. Я думаю, что они изменили способ работы автозагрузчика ... Подробнее см. руководства по рельсам для автозагрузки и перезагрузки констант