web-dev-qa-db-ja.com

Rackミドルウェアファイルをどこに配置して必要ですか?

私は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行で初期化されていない定数エラーが発生します。それは非常に早く混乱する可能性があります。これはイニシャライザのどこかに隠れていたほうがいいです。

これを置くための従来の場所はありますか?


このバウンティで探している具体的な答えは次のとおりです:environment.rbファイルが乱雑にならないようにrequire行を配置できますが、config.middleware.use呼び出しの前にロードされますか? =私が試したことはすべて、初期化されていない一定のエラーにつながります。


pdate:Rails 3.0を使用しているため、Railsアプリを他のRackアプリと同じように扱います。コードファイルはミドルウェアはlib(またはGemfileにリストされているgem)に入っており、config.ruに必須でロードされます。

42
Adam Lassek

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"
48
Mike Jarema

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、コードで参照するとオートロードされます。

23
Chris Heald

私のRails 3.2アプリでは、@ MikeJaremaが説明したように、ミドルウェアTrafficCopapp/middleware/traffic_cop.rbに配置することでロードできました。次に、この行を追加しました指示どおり、私の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はまだTrafficCopクラスを見つけようとしていないので、このようにしてuninitialized constantエラーを回避します。しかし、ミドルウェアスタックでは、文字列を定数化します。このときまでに、app/middlewareはロードパスにあるため、クラスは正しくロードされます。

11
Craig Walker

Rails 3の場合:

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

これまでの作業ソリューションでは、ミドルウェア要件をconfig/middleware.rbに移動し、そのファイルをenvironment.rbに要求して、それを私が共存できる単一の要件に削減しています。

Railsにミドルウェアを追加するというこの一見基本的な問題を他の人々がどのように解決したかについて、私はまだ聞きたいです。

0
Adam Lassek

必要なファイルを必要とするイニシャライザを作成し、必要な場所にファイルを残すことができます。

this によると、イニシャライザはラックミドルウェアがロードされる前に実行されます。

0
Jean