44

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

目前我已经解决了,app/middleware但我可以很容易地将它移到vendor/middleware或者可能vendor/plugins/middleware......

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

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

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

有放置这些东西的传统地方吗?


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


更新:现在我们使用的是 Rails 3.0,我将 Rails 应用程序视为任何其他 Rack 应用程序;中间件的代码文件进入lib(或列出的 gem Gemfile),需要并加载到config.ru.

4

7 回答 7

48

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

它“开箱即用”,无需任何明确的 require 语句。

快速示例:

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

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

如果您要向application.rb添加中间件,则需要根据@mltsy 的评论包含引号。

config.middleware.use "CanonicalHost", "example.com"
于 2012-02-09T21:03:59.143 回答
23

你可以把它放进去lib/tableized/file_name.rb。只要您尝试加载的类可以通过其文件名发现,Rails 就会自动加载必要的文件。因此,例如:

config.middleware.use "MyApp::TotallyAwesomeMiddleware"

你会坚持:

lib/my_app/totally_awesome_middleware.rb

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

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

所以我的 stdlib 存在于 中lib/chris_heald/std_lib.rb,当我在代码中引用它时会自动加载。

于 2010-08-13T16:15:15.233 回答
11

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

config.middleware.use TrafficCop

但是,在应用程序启动时,我不断收到此错误:

uninitialized constant MyApp::Application::TrafficCop

明确指定根命名空间也无济于事:

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

由于某种原因(我还没有发现),在 Rails 生命周期的这一点上,app/middleware加载路径中没有包含。如果我删除该config.middleware.use行并运行控制台,我可以TrafficCop毫无问题地访问常量。app/middleware但是在配置时找不到它。

我通过将中间件类名称括在引号中来解决此问题,如下所示:

config.middleware.use "TrafficCop"

这样,我会避免uninitialized constant错误,因为 Rails 还没有尝试找到TrafficCop该类。但是,当它开始构建中间件堆栈时,它会将字符串常量化。此时,app/middleware是在加载路径中,因此该类将正确加载。

于 2013-04-25T04:23:09.583 回答
5

对于 Rails 3:

#config/application.rb
require 'lib/rack/my_adapter.rb'
module MyApp
  class Application < Rails::Application
    config.middleware.use Rack::MyAdapter
  end
end
于 2010-08-12T00:08:34.700 回答
0

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

于 2010-08-07T09:07:57.227 回答
0

您可以创建一个需要必要文件的初始化程序,然后将文件放在您想要的任何地方。

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

于 2010-08-11T11:56:42.627 回答
0

到目前为止,我所拥有的工作解决方案是将中间件要求移动到config/middleware.rb并要求该文件environment.rb,将其减少到我可以接受的单个要求。

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

于 2010-08-12T00:05:37.467 回答