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