2010-08-06 152 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