我是猴子修補的東西,如一個Rails引擎:如何猴子補丁程序在Rails中自動加載的代碼?
SomeClass.class_eval do
# ...
end
我第一次打的網站中,在發展模式至少,它的工作原理,但它就像我的補丁,第二次根本不存在。我認爲它是Rails自動重新加載引擎(安裝在供應商/),而不是重新加載我的代碼。這是Rails 2.3。
任何想法如何做到這一點,使我的代碼也重新加載?
我是猴子修補的東西,如一個Rails引擎:如何猴子補丁程序在Rails中自動加載的代碼?
SomeClass.class_eval do
# ...
end
我第一次打的網站中,在發展模式至少,它的工作原理,但它就像我的補丁,第二次根本不存在。我認爲它是Rails自動重新加載引擎(安裝在供應商/),而不是重新加載我的代碼。這是Rails 2.3。
任何想法如何做到這一點,使我的代碼也重新加載?
不幸的是,沒有辦法掛鉤Rails 2.x的重載機制。 你可以做的是將你的補丁放在應用程序或lib目錄中的某個地方。 (lib/core_ext
可能是首選位置)。然後將該目錄添加到配置中的autoload_paths。
您可能還需要打開該類,而不是使用class_eval。
monkey-patch已經在lib /上,它已經在Rails 2上的autoload_paths中。我不確定爲什麼,但是用class關鍵字而不是class_eval結果打開該類成爲一個錯誤,稍後拋出一個異常。 – Pablo 2010-12-16 13:01:12
如果將修補程序放在/ config/initializers中的任何.rb文件中,它應該可以工作。
使用class_eval和to_prepare有什麼區別? – montrealmike 2013-10-14 16:29:10
這很醜陋,但我發現如果我將這種代碼放在environments.rb的底部,它始終保證啓動時的正確加載順序。
編輯:此解決方案僅適用於Rails 3+,因爲它依賴於Rails :: Railtie中的某些功能。將此代碼放入初始化程序中。
這個問題是很老,但這裏有一個解決方案,我發現:
Rails.configuration.to_prepare do
SomeClass.class_eval do
# ...
end
end
這迫使Rails的重新加載在發展模式,每個請求的類,但只生產一次。
我剛寫了我的第一個猴子補丁,所以需要圍繞它制定一套約定。這是我想出的:
請將您的擴展名放在lib/ext/
之下。 (由#rubyonrails IRC房間老將workmad3建議)就我而言,我加入一個方法到Mail::Message
類(從mail
寶石,由使用的ActionMailer),所以我創建:
/lib/ext/mail/message.rb
打開類或模塊,並添加代碼:
module Mail class Message def to_is_phone? !!(self.to.first =~ /^\+1\d{10}$/) end end end
創建initalizer加載所有的猴子補丁。 Rails會在引用常量時自動加載文件,但由於您將方法添加到現有的類/模塊而不是定義新的類,所以這不起作用,因此您必須手動需要所有的猴子補丁。因此,我創建:
/config/initializers/monkey_patches.rb
其中包含:
require 'ext/mail/message'
看一看這塊寶石是如何處理「裝潢」又名猴在發動機反之亦然修補的東西:
我碰到過類似的問題,唯一可以解決的方法是通過在開發機器上運行導軌生產模式:(。我也對此感興趣。 – kikito 2010-12-16 12:40:29
@egarcia:哎喲,我希望這次能找到更好的解決方案。 – Pablo 2010-12-16 12:42:08
你如何運行你的代碼,是webbrick,mongrel還是passenger?請發佈rails和服務器版本。 – mpapis 2010-12-20 23:15:43