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

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

目前我已经选择了app/middleware但我可以轻松地将其转移到vendor/middlewarevendor/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,我像其他Rack应用程序一样对待Rails应用程序; 中间件的代码文件进入lib (或Gemfile列出的Gemfile ),并且需要并在config.ru加载。


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

它在没有任何明确的要求声明的情况下“即装即用”。

快速示例:

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

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并尝试自动加载与缺少的常量相对应的文件。 只要确保你的名字匹配,而你是肉汁。 Rails甚至提供了漂亮的帮助程序,可以帮助您轻松识别文件的路径:

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

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


在我的Rails应用程序3.2,我能得到我的中间件TrafficCop通过将其在加载app/middleware/traffic_cop.rb ,就像@MikeJarema描述。 然后按照指示将此行添加到我的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处于加载路径中,因此该类将正确加载。

链接地址: http://www.djcxy.com/p/60357.html

上一篇: Where do you put your Rack middleware files and requires?

下一篇: In Rails, a Sweeper isn't getting called in a Model