红宝石-您将Rack中间件文件和需求放在哪里?

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

目前我已经定居于lib,但我可以轻松地将其移至Gemfileconfig.ru ...

最大的问题是必须在lib的顶部需要单个文件

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

否则在lib行上会出现未初始化的常量错误。 这可能很快就会变得混乱。 我宁愿将它藏在某个地方的初始化程序中。

有没有放置这些东西的常规场所?


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


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

7个解决方案
48 votes

从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"
Mike Jarema answered 2020-08-11T22:23:42Z
23 votes

您可以将其放在lib/chris_heald/std_lib.rb中。只要要通过其文件名发现要加载的类,Rails就会自动加载所需的文件。 因此,例如:

config.middleware.use "MyApp::TotallyAwesomeMiddleware"

您将继续:

lib/my_app/totally_awesome_middleware.rb

Rails捕获const_missing和attemts来自动加载与缺少的常量相对应的文件。 只要确保您的名字匹配并且您是肉汁。 Rails甚至提供了漂亮的帮助程序,它们将帮助您轻松地确定文件的路径:

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

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

Chris Heald answered 2020-08-11T22:24:16Z
11 votes

在我的Rails 3.2应用程序中,我可以通过将其放置在TrafficCop来加载我的中间件uninitialized constant,就像@MikeJarema所描述的那样。 然后,按照指示将这行添加到我的app/middleware中:

config.middleware.use TrafficCop

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

uninitialized constant MyApp::Application::TrafficCop

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

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

由于某些原因(我尚未发现),在Rails生命周期中,加载路径中未包括uninitialized constant。 如果删除TrafficCop行并运行控制台,则可以毫无问题地访问app/middleware常量。 但是在配置时在app/middleware中找不到它。

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

config.middleware.use "TrafficCop"

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

Craig Walker answered 2020-08-11T22:24:59Z
4 votes

对于Rails 3:

#config/application.rb
require 'lib/rack/my_adapter.rb'
module MyApp
  class Application < Rails::Application
    config.middleware.use Rack::MyAdapter
  end
end
yfeldblum answered 2020-08-11T22:25:19Z
0 votes

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

John Topley answered 2020-08-11T22:25:39Z
0 votes

您可以创建一个初始化器,该初始化器需要必需的文件,然后将文件保留在所需的位置。

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

Jean answered 2020-08-11T22:26:04Z
0 votes

到目前为止,我的工作解决方案是将中间件需求移至config/middleware.rb,并将该文件移至environment.rb中,从而将其减少到一个我可以使用的需求。

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

Adam Lassek answered 2020-08-11T22:26:35Z
translate from https://stackoverflow.com:/questions/3428343/where-do-you-put-your-rack-middleware-files-and-requires