2009-04-14 50 views
5

瞭解軌道緩存如何工作的人可以真正幫助我在這裏。下面的代碼,嵌套了Rails :: Initializer.run塊內:在environment.rb中設置的常量在開發模式下消失

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,我一定要重新啓動服務器。有沒有什麼辦法可以在環境文件中設置常量並讓它們在開發模式下正常工作?爲什麼第一個請求中存在常量,而不是以下請求?

UPDATE:由於environment.rb文件是隻讀的,當Rails應用程序被啓動,我想我的兩個LIB文件和模型對每個請求重新加載,我被迫常數遷入some_class.rb文件如下所示:

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

而在environments/production.rb中,我有舊的const_set代碼。

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

回答

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 
+0

謝謝,這就是我正在尋找的答案。 – joshuaxls 2009-04-14 05:53:32

1

生產模式預加載所有類,而在開發模式下,根據需要加載類讀取配置文件。手動在你的配置中要求它們強制在配置階段之前/期間讀取類。

+0

我仍然不知道爲什麼,雖然它的工作原理上的第一個請求,而不是下面的請求。你知道有什麼方法可以在環境文件中設置常量,以使它們堅持開發模式嗎?我正在對some_class.rb進行大量更改,並且不想繼續重新啓動服務器。 – joshuaxls 2009-04-14 03:32:56

相關問題