我一直在用 rails 3 和 bundler 左右战斗。如果尚未加载 rails 应用程序,则有一些 gem 无法正常工作。factory_girl 和 shoulda 都是示例,即使在 rails3 分支上也是如此。以 shoulda 为例,尝试运行时rake test:units
出现以下错误:
DEPRECATION WARNING: RAILS_ROOT is deprecated! Use Rails.root instead. (called from autoload_macros at c:/code/test_harness/vendor/windows_gems/gems/shoulda-2.10.3/lib/shoulda/autoload_macros.rb:40)
c:/code/test_harness/vendor/windows_gems/gems/shoulda-2.10.3/lib/shoulda/autoload_macros.rb:44:in 'join': can't convert #<Class:0x232b7c0> into String (TypeError)
from c:/code/test_harness/vendor/windows_gems/gems/shoulda-2.10.3/lib/shoulda/autoload_macros.rb:44:in 'block in autoload_macros'
from c:/code/test_harness/vendor/windows_gems/gems/shoulda-2.10.3/lib/shoulda/autoload_macros.rb:44:in 'map'
from c:/code/test_harness/vendor/windows_gems/gems/shoulda-2.10.3/lib/shoulda/autoload_macros.rb:44:in 'autoload_macros'
from c:/code/test_harness/vendor/windows_gems/gems/shoulda-2.10.3/lib/shoulda/rails.rb:17:in '<top (required)>'
深入挖掘 lib/shoulda/rails,我看到了:
root = if defined?(Rails.root) && Rails.root
Rails.root
else
RAILS_ROOT
end
# load in the 3rd party macros from vendorized plugins and gems
Shoulda.autoload_macros root, File.join("vendor", "{plugins,gems}", "*")
所以......这里发生的事情是在定义 Rails.root 时,Rails.root == nil,所以使用 RAILS_ROOT,并且 RAILS_ROOT==nil,然后将其传递给 Shoulda.autoload_macros。显然,rails 应用程序尚未初始化。现在使用 Bundler 的 Rails3,在 Bundler 方面有一些关于能够指定需要 gem 的顺序的喧嚣,但我不确定这是否会解决手头的问题。
最终我的问题是: environment.rb 文件(实际初始化应用程序)何时被拉入?初始化应用程序并在 config/application.rb 中的 Bundler.require 行之前发生碰撞是否有任何危害?我试图破解 bundler 来自己指定顺序,并首先拉入 rails gem,但在我看来,需要 rails gem 并没有真正初始化应用程序。
由于在初始化应用程序之前调用了这一行(在 config/application.rb 中),因此捆绑程序 Gemfile 中需要初始化 rails 的任何 gem 都会失败。
# Auto-require default libraries and those for the current Rails environment.
Bundler.require :default, Rails.env