0

我有一個寶石:如何讓Rails停止重新加載我的寶石?

# in /Library/Ruby/Gems/1.8/gems/my_gem-1.0.0/lib/my_gem.rb 
module MyGem 
    def do_stuff 
    .. 
    end 
end 

而且我裝它的Rails:

# in [rails_root]/config/environment.rb: 
config.gem 'my_gem', :version => '1.0.0' 

,並用它:

# in [rails_root]/app/controllers/application_controller.rb 
class ApplicationController < ActionController::Base 
    include MyGem 
end 

但我需要猴子補丁有點在特定環境的方式:

# in [rails_root]/config/environments/development.rb: 
MyGem.class_eval do 
    def do_stuff 
    raise 'Ack! - just testing' 
    end 
end 

不幸的是,MyGem重新加載每個請求,所以我的猴子補丁是無用的。

我檢查load_once_paths

ActiveSupport::Dependencies.load_once_paths 
# => ["/Library/Ruby/Gems/1.8/gems/my_gem-1.0.0/lib", "other stuff"] 

任何想法我如何能得到我想要的效果?

回答

3

似乎您正在開發模式下工作,其中Rails在每個請求中加載所有類以幫助開發人員反映代碼更改+您已將gem包含在控制器中。爲了克服這一點去project_path /配置/環境/ development.rb,除非你重新啓動服務器加入這一行

,你不會有你的代碼更改
config.cache_classes = true 

公告反映。

更新1: 另外,作爲第二解決方案後,你,你包括在控制器中的寶石,你可以添加moneky補丁。您可以將其添加到控制器文件的底部。

更新2:第三個方案(推薦)如果你可以添加以下代碼段my_gem.rb

class ActionController::Base 
    include MyGem 
end 

那麼事情應該工作,你將不再需要手動將其包括在你的應用控制器。

0

如果您在您的environment.rb中包含寶石,則不需要將它包含在控制器中。

您可能想要考慮gem如何掛入ActionController - 聽起來您想要將類方法添加到ActionController :: Base中,這非常簡單。看看有多少常見的寶石實現這一點。

這聽起來太像了,你甚至可能想檢查的值RAILS_ENV以確保不同環境的不同行爲。

+0

我正在_requiring_它(隱式地)在environment.rb;我在ApplicationController中_including_它。這些是非常不同的行爲。我想知道的是爲什麼Rails每次重新加載ApplicationController時都會重新加載gem。證明它這樣做是因爲我的猴子補丁消失了。 – 2009-07-23 12:17:30