Перезагрузите инициализатор Rails 3 в режиме разработки - PullRequest
6 голосов
/ 07 февраля 2011

Я создаю приложение на Rails 3, где пользователи могут выбрать один из нескольких шаблонов и создать небольшой веб-сайт. Я пытаюсь инициализировать все доступные шаблоны при запуске приложения. По сути, это файл, который позволяет мне определить их все, затем вызывает Template.add(template) для каждого из них, который, в свою очередь, сохраняет их в @@templates, и я могу получить к ним доступ через Template.find(name).

Проблема в том, что в режиме разработки, инициализатор, который я звонил на Template.add, загружается при первом запросе, а затем стирается на reload!. Я прочитал о config.to_prepare, но он не работает для меня, вероятно, потому что мне требуются такие шаблоны:

# template config at app/templates/template_name/template_name.rb
path = File.expand_path(Rails.root + 'app/templates')
Dir[File.join(path, '/*')].each do |template|
  name = File.basename(template)
  require File.join(path, name, "#{name}.rb")
end

Что я могу сделать, чтобы либо перезагрузить эти файлы после reload!, либо вообще не допустить их перегрузки? Кроме того, если у вас есть рекомендации для лучшего способа справиться с этим, я весь слух. Я все еще хорошо разбираюсь в Rails, особенно в том, что касается конфигурации.

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

Ответы [ 2 ]

1 голос
/ 17 февраля 2012

Я думаю, вы должны быть в состоянии сделать это с config.to_prepare, если вы переместите свои вызовы на Template.add из файлов template_name.rb (я полагаю, что они там сейчас), и в ваш код загрузки. сразу после require. Например, рассмотрите возможность добавления этого метода класса в ваш класс Template, а затем, возможно, даже вызываете его из самого класса, когда он впервые загружается:

class Template
  def self.load_all
    # template config at app/templates/template_name/template_name.rb
    path = File.expand_path(Rails.root + 'app/templates')
    Dir[File.join(path, '/*')].each do |template|
      name = File.basename(template)
      require File.join(path, name, "#{name}.rb")

      # Register the template even if the class itself is already loaded.
      Template.add(name)
    end
  end

  # Initially load all templates.
  Template.load_all
end

Затем удалите код Template.add(name) из файлов template_name.rb, в которых они регистрируются. (Опять же, я предполагаю, что именно здесь это и происходит в настоящее время - мне не совсем ясно об этом из вашего исходного поста.) Или, возможно, вы просто хотите убедиться, что Template.add является идемпотентом и молча отбрасывает дубликаты.

Наконец, добавьте следующее к config/environments/development.rb:

config.to_prepare do
  Template.load_all
end

Это перезагрузит все ваши шаблоны после перезагрузки класса Template.

Я не пробовал этого, но с вызовом Template.load_all, который я предложил в конце Template класса, вам может даже не понадобиться config.to_prepare часть.

1 голос
/ 12 февраля 2011

Как насчет сохранения поиска имен шаблонов в их файлах в хранилище памяти, таком как memcached или Redis, или даже в базе данных.Инициализатор может загрузить хранилище памяти или убедиться, что база данных обновлена ​​со всеми значениями, а затем Template.find может просто просмотреть хранилище, чтобы увидеть, где находятся файлы, или даже просто получить имя класса, еслиуже будет загружен.Просто увидев, определено ли имя класса, можно сказать, требуется ли вам файл шаблона или просто создать свой новый экземпляр.

В основном хранить @@templates вне памяти процесса rails или, по крайней мередостаточно информации, чтобы вы могли собрать необходимые детали @@templates на лету.

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