Константы, установленные в environment.rb, исчезают в режиме разработки - PullRequest
5 голосов
/ 14 апреля 2009

Кто-то, кто понимает, как работает кэширование рельсов, может действительно помочь мне здесь. Вот код, вложенный в блок Rails :: Initializer.run:

config.after_initialize do
  SomeClass.const_set 'SOME_CONST', 'SOME_VAL'
end

Теперь, если я запусту script/server и сделаю запрос, все будет отлично. Тем не менее, во втором запросе к моему приложению Rails все идет к черту с унифицированной постоянной ошибкой. В производственном режиме я могу успешно выполнить второй запрос, то есть константа все еще там.

Я исправил проблему, изменив вышеприведенное на:

config.after_initialize do
  require 'some_class' # in RAILS_ROOT/lib/some_class.rb
  SomeClass.const_set 'SOME_CONST', 'SOME_VAL'
end

Но теперь это означает, что когда бы я ни вносил изменения в some_class.rb, я должен перезапускать сервер. Есть ли способ установить константы в файле среды и правильно ли они работают в режиме разработки? Почему константа существует в первом запросе, а не в следующем?

ОБНОВЛЕНИЕ: Поскольку environment.rb читается только при загрузке приложения Rails, и я хочу, чтобы мои файлы lib и модели перезагружались при каждом запросе, я был вынужден переместить константы в some_class Файл .rb выглядит следующим образом:

if Rails.env.development?
  const_set 'SOME_CONST', 'SOME_DEVELOPMENT_VAL'
end

А в средах / production.rb у меня есть старый код const_set.

ОБНОВЛЕНИЕ: Еще лучший способ с использованием config.to_prepare подробно описан ниже.

Ответы [ 2 ]

9 голосов
/ 14 апреля 2009

Он работает только для первого запроса в режиме разработки, поскольку классы перезагружаются при каждом запросе. Так что по первому запросу константа задается в инициализаторе, и все хорошо. Затем, при следующем запросе, он перезагружает класс БЕЗ повторного запуска бита из вашего инициализатора, поэтому константа не устанавливается с этого момента.

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

Так что вы можете установить константу либо в модели, либо в config.to_prepare вместо config.after_initialize. to_prepare вызывается перед каждым запросом.

В модели:

class SomeClass < ActiveRecord::Base
  MY_CONST = "whatever"

  # You can access MY_CONST directly, but I tend to wrap them in a class 
  # method because literal constants often get refactored into the database.
  def self.my_const
    MY_CONST 
  end
end

В конфиге:

# This will run before every single request. You probably only want this in
# the development config.
config.to_prepare do
  SomeClass.const_set 'SOME_CONST', 'SOME_VAL'
end
1 голос
/ 14 апреля 2009

Рабочий режим предварительно загружает все классы, тогда как в режиме разработки классы загружаются по мере необходимости, после файлы конфигурации считываются. Ручное требование их в ваших конфигах вынуждает классы быть прочитанными до / во время стадии конфигурации.

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