environment.rb中设置的常量在开发模式下消失

时间:2009-04-14 02:01:25

标签: ruby-on-rails ruby

了解rails缓存如何工作的人可以真正帮助我。这是代码,嵌套在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进行更改时,我都必须重新启动服务器。有没有办法在环境文件中设置常量并让它们在开发模式下正常工作?为什么常量存在于第一个请求中,而不是以下请求?

更新:由于只在启动Rails应用程序时读取了environment.rb,并且我希望在每个请求上重新加载我的lib文件和模型,我被迫将常量移动到some_class.rb文件如下:

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

在environment / production.rb中,我有旧的const_set代码。

更新:使用config.to_prepare的更好方法详述如下。

2 个答案:

答案 0 :(得分:9)

它仅适用于开发模式下的第一个请求,因为每个请求都会重新加载类。所以在第一次请求时,在初始化器中设置常量,一切都很好。然后在下一个请求中,重新加载类而不重新运行初始化程序中的位,因此不会从那里开始设置常量。

它在生产模式下工作,因为不会为每个请求重新加载类,所以每次都不会丢失那个类的状态。

因此,您可能希望在模型中设置常量,或者在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 :(得分:1)

生产模式预加载所有类,而在开发模式下,根据需要加载类,在读取配置文件之后。在配置中手动要求它们强制在配置阶段之前/期间读取类。