У меня возникла проблема с тем, как автозагрузка Rails работает в средах разработки/тестирования. То, что я пытаюсь достичь, - это нечто вроде подключаемых реализаций для родительского класса, которые могут быть изменены при запуске приложения. Более подробно, я реализовал класс Measure
со следующей идеей:Rails автозагрузка: константы теряются между тестами или введены циклические зависимости
# app/models/measure.rb
class Measure
attr_reader :implementations
def self.register(klass)
@implementations << klass
end
def self.from(raw_value)
# ... find a suitable implementation and instantiate it
end
# ...
end
И тогда я реализации различных Measures
, такими как:
# app/models/measures/grams.rb
module Measures
class Grams < Measure
# ... code to tell Measures if this class can be
# instantiated from a given raw value
end
end
Затем они должны быть установлены с вызовами такими как Measure.register(Measures::Grams)
.
Проблема заключается в том, что если я делаю это в инициализаторе, реализации мер теряются между прогонами, поскольку постоянный кеш, по-видимому, очищается. Это означает, что вызов, такой как Measure.from("2 grams")
, который должен быть действительным, больше не работает, поскольку Measure.implementations
не содержит Measures::Grams
. Если, с другой стороны, я добавляю require_dependency
в app/models/measure.rb
, ссылаясь на некоторый код, который выполняет регистрацию, у меня есть циклическая зависимость при ссылке на одну из реализаций до того, как Rails загрузил класс Measure
. После довольно много возиться и читать о том, как Rails делает автозагрузку, я не смог найти удовлетворительное решение.
Итак, мой вопрос: как настроить эту иерархию, чтобы хорошо поиграть с тем, как Rails автозагружает код?