【发布时间】:2023-10-28 17:39:01
【问题描述】:
我有一个使用 Bundler 设置的 Rails 项目。我捆绑的其中一个 gem 提供了一个 Rack 中间件,我想在我的 Rails 应用程序中使用它(但只能在“生产”Rails 环境中使用)。
如果我只是在config/environments/production.rb 中输入这样的内容,我会得到一个未知的常量错误:
config.middleware.use ::Rack::MyMiddleware
...大概是因为此时尚未调用Bundler.require,并且我的捆绑 gem 都不可用。
我找到了一些解决此问题的方法,但似乎都不是很好,我想知道是否有我缺少的更标准的解决方案:
- 在
config/environments/production.rb中明确require 'my_middleware_gem' - 将
config.middleware.use调用包装在after_initialize块中,确保 Bundler 在我尝试引用常量之前有机会完成它的工作。 - 使用字符串 (
"::Rack::MyMiddleware") 代替裸类常量。由于某种原因,这似乎不适用于 Unicorn,但确实适用于其他一些服务器(对于 Unicorn,它最终会尝试调用"::Rack::MyMiddleware".new,这当然会失败)。
我错过了一些更好的方法吗?预计在初始化过程中的什么时候捆绑的 gem 应该可用?
【问题讨论】:
-
捆绑的 gems 应该在您的环境中可用 - 在
require 'rails/all'之后调用Bundle.require。 gem 的名称是什么,与所需文件的名称相同吗?你的Gemfile中需要gem 'my_middleware_gem', :require => 'rack/my_middleware' 之类的东西吗?见:gembundler.com/gemfile.html -
抱歉,我忘了说我还在使用 Rails 2.3.8(我知道,我知道),设置在gembundler.com/rails23.html 中描述。我怀疑 Rails 2 关于何时调用 Bundler.require 的行为可能会有所不同。不过,关于您的建议 - gem 的名称与使用它所需的 require 语句相匹配,并在我的添加
:require选项Gemfile 似乎对这种特殊行为没有影响。 -
我错了——
Gemfile在 Rails 2 和 3 中的环境 之后 才会加载。看起来 Rails 自动加载常量 确实如此 虽然有效,有时这就足够了,但在这种情况下似乎不行。 -
我认为在这种情况下使用
after_initialize块是正确的方法。 -
是的,这就是我最终的结果。谢谢!关于原始问题中提到的独角兽问题,原来我遇到了这个问题:davidvollbracht.com/blog/…
标签: ruby-on-rails bundler rack middleware