44

私は、Rails アプリケーションに組み込まれたいくつかのロジックをミドルウェアにリファクタリングしている最中です。私が遭遇した 1 つの煩わしさは、それらを配置する場所に関する規則がないように見えることです。

現在、私は落ち着いて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ステートメントがなくても、「すぐに」動作します。

簡単な例:

app/middleware/canonical_host.rbに実装されているCanonicalHostというミドルウェア クラスを使用しています。次の行を 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この行を my に追加しました。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"

このようにして、Rails はまだクラスuninitialized constantを見つけようとしていないため、エラーを回避できます。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

私がこれまでに持っている実用的な解決策は、ミドルウェアの require を に移動し、config/middleware.rbそのファイルをenvironment.rbrequire して、それを私が一緒に暮らすことができる単一の require に減らすことです。

Rails にミドルウェアを追加するという一見基本的な問題を他の人がどのように解決したかを知りたいです。

于 2010-08-12T00:05:37.467 に答える