Почему Rails пытается угадать имя файла, когда я включаю модуль?

У меня есть следующая настройка, в которой один из моих классов включает модуль, расположенный в другом файле

Главное отметить, что модуль MyBar не живет в файле с похожим именем. Он живет в my_foo.rb.

my_foo.rb

module MyBar
 def self.test
 "This is a test string"
 end
end

some_class.rb

require 'my_foo'
class SomeClass
 include MyBar
 def initialize
 puts MyBar.test
 end
end

Когда я запускаю это, я получаю NameError

NameError - uninitialized constant MyBar

Похоже, что Rails пытается быть умным и предположить, что, поскольку имя модуля MyBar, оно должно быть расположено в файле с именем my_bar.rb.

Я попытался проверить эту теорию, изменив имя на то, что он ожидает, и он внезапно работал правильно

my_foo.rb (renamed)-> my_bar.rb

Вопрос:

  • Почему Rails делает это? Похоже, что это слишком много. Я понимаю, что это "соглашение по конфигурации", но есть несколько веских причин, по которым имя файла не совпадает с именем модуля.

  • Как переопределить это поведение?

2 ответа

Это связано с тем, как автозагрузка работает в Rails.

Удаляет только автоматические загрузки при попытке использовать новое имя класса/модуля, которое соответствует имени файла и находится в каталоге /lib/.

Чтобы устранить проблему, вы можете поместить свой файл my_foo.rb в каталог /lib/ и выполнить его следующим образом: require 'lib/my_foo'

Для получения дополнительной информации о том, как работает автозагрузка в Rails, см. документацию Rails для Автозагрузка и перезагрузка констант.


Каталог app не включен в $LOAD_PATH в рельсах по разным причинам (в основном автозагрузка и перезагрузка класса при редактировании материалов).

Если вы хотите использовать константы, которые не соответствуют имени файла, вы хотите найти их в каталоге lib и потребовать их (lib включен в $LOAD_PATH).

Если вы действительно хотите включить файл в каталог app, вы, вероятно, захотите попробовать с помощью require Rails.root.join('app', 'models', 'my_foo.rb').to_s. Я не уверен, что сломается, вы действительно согласны с рельсами.

licensed under cc by-sa 3.0 with attribution.