我有一个宝石:
# 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"]
知道我怎么能得到我想要的效果吗?
答案 0 :(得分:3)
似乎您正在开发模式下,Rails在每个请求中加载所有类,以帮助开发人员反映代码更改+您已将gem包含在控制器中。要解决这个问题,请转到project_path / config / environments / development.rb并添加此行
config.cache_classes = true
请注意,除非重新启动服务器,否则不会反映您的代码更改。
更新1 : 另外,作为第二种解决方案,您可以在将控制器中包含gem后添加moneky补丁。您可以将其添加到控制器文件的底部。
更新2 :第三种解决方案(推荐)如果您可以将以下代码段添加到my_gem.rb
class ActionController::Base
include MyGem
end
然后事情应该有效,因为您不需要手动将其包含在应用程序控制器中。
答案 1 :(得分:0)
如果您在environment.rb
中加入了宝石,则不需要将其包含在控制器中。
您可能想要考虑gem如何挂钩到ActionController中 - 听起来您想要将类方法添加到ActionController :: Base,这非常简单。看看有多少常见的宝石实现了这一点。
这听起来也像你甚至想要检查存在与否值RAILS_ENV
以确保不同环境的不同行为。