RoR: MyModel.descendants возвращает [] в представлении после первого вызова? - PullRequest
9 голосов
/ 04 мая 2011

Я хочу отобразить список выбора подклассов MyModel в представлении. Это еще не работает, поэтому для проверки работоспособности я включил это в свое представление:

<%= MyModel.descendants %>

первый раз, когда я отображаю эту страницу после перезапуска сервера, она показывает список потомков (их шесть). Все последующих раз он отображается как пустой список [].

FWIW, в моих инициализаторах есть оператор require:

Dir[Rails.root.join("app/models/my_models/**/*.rb").to_s].each {|f| require f}

... и я убедился, что они становятся необходимыми.

Что за @ ($% & происходит?

Ответы [ 3 ]

9 голосов
/ 13 марта 2012

У меня была такая же проблема.Решил это, добавив config/initializers/preload_models.rb с:

Dir[Rails.root + 'app/models/*.rb'].map {|f| File.basename(f, '.*').camelize.constantize }

Надеюсь, что кому-нибудь поможет.

7 голосов
/ 16 июня 2015

Я просто включил активную загрузку в каждой среде:

config.eager_load = true

Это работало для меня даже при использовании пространств имен для имен классов.

7 голосов
/ 07 мая 2011

Когда вы используете require, даже если ваш my_model.rb перезагружен, ядру не потребуются ваши файлы подклассов .rb, потому что они уже были загружены. Тебе придется пройти через автозагрузку рельсов.

Обычно, по вашему первому запросу, rails автоматически загружается MyModel из my_model.rb, что требует my_models/sub_model.rb. Класс SubModel наследует MyModel, который заполняет массив descendants. Однако по вашим следующим запросам rails автоматически загружается MyModel (эй, вы находитесь в режиме разработки), что снова требует my_models/sub_model.rb. Но на этот раз ядро ​​знает, что оно уже загрузило этот файл и не будет загружать его снова.

Я столкнулся с этой проблемой час назад, что привело меня к вашему посту и поиску решения. Нам нужны rails для автозагрузки подклассов при каждом вызове вашего основного класса.

Вот решение:

class MyModel
  Dir[File.join(File.dirname(__FILE__),"my_models","*.rb")].each do |f|
    MyModels.const_get(File.basename(f,'.rb').classify)
  end
end

Эти строки, вероятно, могут быть выведены за пределы класса. Этого должно быть достаточно (это для меня), если у вас есть файлы только в my_models, а не в подкаталогах. Если у вас есть некоторые (например, MyModels::Car::Ford, вам может потребоваться поместить такие же вещи в подмодули (в my_models/car.rb).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...