Почему Rails не обновляет классы по каждому запросу (несмотря на конфигурацию)?
Недавно мне пришлось перезапускать сервер разработки каждый раз, когда я меняю свой код. Мое развитие.в файле rb все еще есть эта строка:
config.cache_classes = false
Я попытался с помощью отладчика проверить, что это значение застряло. Для этого я установил свою конфигурацию в глобальную переменную в среде.РБ:
$my_initializer = Rails::Initializer.run do |config| ... end
Затем я вставил строку debugger
в один из своих контроллеров, чтобы я мог сделать это:
(rdb:2) $my_initializer.configuration.cache_classes false
Таким образом, исключалась возможность того, что значение cache_classes
устанавливалось в true
в другом месте. Я пробовал использовать и Mongrel, и WEBrick, и это все еще происходит.
что еще может заставить Rails не перезагружать мой код с каждым запросом?
Я бегу.:
Дворняга 1.1.5
WEBrick 1.3.1
Рельсы 2.3.8
Ruby 1.8.7 p253
Править: по предложению @Daemin я проверил, что mtime моих файлов на самом деле обновляется, когда я сохраняю их в своем текстовом редакторе (Textmate)
merced:controllers lance$ ls -l people_controller.rb -rwxr-xr-x 1 lance staff 2153 Act 10 18:01 people_controller.rb
Затем я внес изменения и сохранил файл:
merced:controllers lance$ ls -l people_controller.rb -rwxr-xr-x@ 1 lance staff 2163 Oct 11 12:03 people_controller.rb
Так что это не проблема с mtimes.
5 ответов:
Если у кого-то еще есть эта проблема, то решение было таким:
config.threadsafe!
должно прийти раньшеconfig.cache_classes
. Переупорядочить его так, чтобы исправить это:... config.threadsafe! config.cache_classes = false ...
Таким образом, получается, что
config.threadsafe!
перезаписывает эффектconfig.cache_classes = false
, хотя на самом деле он не перезаписывает значениеcache_classes
(см. мой вопрос для доказательства). Покопавшись немного больше в исходном коде Rails, можно понять, почему это может быть, но мне на самом деле не нужно threadsafe поведение в моей среде разработки. Вместо этого Я заменил свой вызов наconfig.threadsafe!
в среде.rb toconfig.threadsafe! unless RAILS_ENV == "development"И все работает теперь нормально.
Я подозреваю, что классы, которые вы ожидаете обновить, были "обязательными" где-то в вашей конфигурации. Обратите внимание, что загрузка зависимостей Rails происходит после того, как произошли
require
S Ruby. Если определенный модуль или класс уже был необходим, он не будет обработан загрузчиком зависимостей Rails и, следовательно, не будет перезагружен. Подробное объяснение можно найти в этой статье: http://spacevatican.org/2008/9/28/required-or-not
Несмотря на то, что threadsafe! решение работает, я также хотел бы отметить для вашей пользы и других, которые могут появиться после следующего...
Если вы редактируете код движка, который находится непосредственно в каталоге поставщика/движков, эти файлы не будут обновлены без перезагрузки. Для включения такой функциональности может существовать опция конфигурации. Тем не менее, это очень важно помнить, если вы использовали движки, чтобы отделить большие биты функциональности от вашего приложение.