你把你的Rack中间件文件放在哪里?

我正在将一些内置于Rails应用程序中的逻辑重构为中间件,而我遇到的一个烦恼就是似乎缺乏将它们放在哪里的惯例。

目前我已经解决了app/middleware但我可以轻松地将其移动到vendor/middlewarevendor/plugins/middleware

最大的问题是必须要求config/environment.rb顶部的单个文件

 require "app/middleware/system_message" require "app/middleware/rack_backstage" 

否则我会在config.middleware.use行中得到未初始化的常量错误。 这可能很快就会变得混乱。 我宁愿把它藏在某个地方的初始化程序中。

有没有一个传统的地方把这东西?


我正在寻找这个赏金的具体答案是: 在哪里可以把需求线,以便他们不混乱的environment.rb文件,但仍然会在config.middleware.use调用之前加载? 我所尝试的一切都会导致未初始化的常量错误。


更新 :现在我们正在使用Rails 3.0,我像其他Rack应用程序一样对待Rails应用程序; 中间件的代码文件进入lib (或Gemfile列出的Gemfile ),并且需要并在config.ru加载。

从Rails 3.2开始,Rack中间件属于app / middleware目录。

它可以“开箱即用”,不需要任何明确的要求声明。

快速示例:

我正在使用一个名为CanonicalHost的中间件类,它在app / middleware / canonical_host.rb中实现 。 我已经在production.rb中添加了以下代码行( 请注意 ,中间件类是明确给出的,而不是引用的string,适用于任何特定于环境的configuration文件):

 config.middleware.use CanonicalHost, "example.com" 

如果您将中间件添加到application.rb ,则需要按照@ mltsy的注释包含引号。

 config.middleware.use "CanonicalHost", "example.com" 

你可以把它放在lib/tableized/file_name.rb 。 只要你正在加载的类可以被其文件名称发现,Rails就会自动加载所需的文件。 所以,例如:

 config.middleware.use "MyApp::TotallyAwesomeMiddleware" 

你会留在:

 lib/my_app/totally_awesome_middleware.rb 

Rails捕获const_missing并尝试自动加载与缺less的常量相对应的文件。 只要确保你的名字匹配,你是肉汁。 Rails甚至提供了漂亮的帮助程序,可以帮助您轻松识别文件的path:

 >> ChrisHeald::StdLib.to_s.tableize.singularize => "chris_heald/std_lib" 

所以我的stdlib位于lib/chris_heald/std_lib.rb ,并且在代码中引用时自动加载。

在我的Rails 3.2应用程序中,我可以通过将它放在app/middleware/traffic_cop.rb加载我的中间件TrafficCop,就像@MikeJarema描述的一样。 然后我按照说明将这一行添加到我的config/application.rb

 config.middleware.use TrafficCop 

但是,在应用程序启动时,我一直得到这个错误:

 uninitialized constant MyApp::Application::TrafficCop 

明确指定根名称空间也没有帮助:

 config.middleware.use ::TrafficCop # uninitialized constant TrafficCop 

出于某种原因(我还没有发现),在Rails生命周期的这一点上, app/middleware不包含在加载path中。 如果我删除了config.middleware.use行,并运行控制台,我可以访问TrafficCop常量没有任何问题。 但是在configuration的时候在app/middleware找不到它。

我通过将中间件类名称用引号括起来解决了这个问题,如下所示:

 config.middleware.use "TrafficCop" 

这样,我会避免uninitialized constant错误,因为Rails没有试图findTrafficCop类。 但是,当它开始构build中间件堆栈时,它将会对string进行常量化。 此时, app/middleware在加载path中,所以类将正确加载。

对于Rails 3:

 #config/application.rb require 'lib/rack/my_adapter.rb' module MyApp class Application < Rails::Application config.middleware.use Rack::MyAdapter end end 

我不知道约定,但为什么不把它放在/lib目录? 那里的文件会被Rails自动加载。

您可以创build一个初始化程序,它需要必要的文件,然后将文件保留在任何您想要的位置。

据此,初始化程序在加载机架中间件之前执行。

到目前为止,我的工作解决scheme是将中间件移到config/middleware.rb并在environment.rb要求这个文件,把它降低到我可以接受的一个单一的要求。

我仍然想听听其他人如何解决这个向Rails添加中间件的这个看似基本的问题。