2010-08-06 196 views
41

我正在重构构建到Rails应用程序中的一些逻辑到中间件中,而我遇到的一个烦恼是看似缺乏将它们放在哪里的约定。你把你的Rack中间件文件放在哪里?

目前我已经看中了app/middleware但我可以很容易地将其移动到vendor/middleware也许vendor/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,我把一个Rails应用程序像任何其他应用程序架;中间件的代码文件进入lib(或Gemfile中列出的宝石),并且需要并加载到config.ru

回答

48

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

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

简单的例子:

我使用的是被称为CanonicalHost这是在应用/中间件/ canonical_host.rb实现中间件类。我已经添加了以下行production.rb(的中间件类是明确给出,而不是带引号的字符串,这对于任何特定的环境配置文件工作):

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

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

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

谢谢,当我更新时,我会记住这一点。 – 2012-02-10 06:22:47

+4

请问您可以添加任何链接以供参考?它不适合我,Google/Rails指南也无济于事......谢谢! – dgilperez 2012-11-08 12:09:38

+0

我意识到我犯了一个愚蠢的错误,把它放在我的根文件夹中,而不是(已经指定的)应用程序文件夹中,这让我很开心。所以,foo_app/app/middleware/file.rb。 – d3vkit 2013-03-28 00:05:40

0

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

+0

直到environment.rb运行后,如果有的话。将它们移动到lib并不能解决未初始化的常量错误。 – 2010-08-08 02:26:53

0

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

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

+0

不是。仍然获得未初始化的常量。 – 2010-08-11 19:22:38

+0

看起来我读起来有点乐观。我猜config.ru不符合你的要求吗? – Jean 2010-08-11 22:23:27

+0

好吧,那需要使用机架而不是脚本/服务器,对吧?如果我必须这样做,我可以这样做,但我真的认为这会比这更简单。 – 2010-08-12 00:02:08

0

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

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

4

对于Rails的3:

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

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

config.middleware.use "MyApp::TotallyAwesomeMiddleware" 

你会密切留意:

lib/my_app/totally_awesome_middleware.rb 

Rails的捕捉const_missing和attemts加载自动对应丢失的常数的文件。只要确保你的名字匹配,而你是肉汁。轨甚至提供极好的助手说会帮你找出容易的文件的路径:

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

所以我STDLIB住在lib/chris_heald/std_lib.rb,当我在代码中引用它自动加载。

+0

我有一些名为'Rack :: Backstage'的中间件。把它放在'lib/rack/backstage.rb'中。单位恒定误差。 – 2010-08-13 20:18:42

+1

如果第一个参数是一个字符串,这将起作用_only_。一旦我明白,成功! – 2010-08-13 21:33:07

+0

很酷的解决方案。 :) – 2010-08-14 05:40:25

11

在我的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未包含在加载路径中。如果我删除了config.middleware.use行,并运行控制台,我可以访问TrafficCop常量没有任何问题。但它在配置时在app/middleware找不到它。

我解决了这个由引号引起中间件类名,比如:

config.middleware.use "TrafficCop" 

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

+0

我在rails 3.2.18上,当我把它放在application.rb中时有相同的问题 - 但是当我把它放在一个特定的环境配置中时,它工作的很好!如果你按照从config.ru开始的加载路径,事实证明application.rb在大多数其他事情之前被加载,然后应用程序被初始化(加载所有动态初始化器,包括中间件),并且其他环境文件在加载后那么,那么中间件常量就定义了! – mltsy 2014-07-07 19:19:19