35

次のようなRackアプリケーションがあります。

class Foo
  def initialize(app)
    @app = app
  end
  def call(env)
    env["hello"] = "world"
    @app.call(env)
  end
end

RackアプリケーションをRailsにフックした後、Rails内からアクセスするにはどうすればよいenv["hello"]ですか?

更新:回答をくれたGaiusに感謝します。Rack and Railsを使用すると、リクエストの期間中、またはセッションの期間中、物を保管できます。

# in middleware
def call(env)
  Rack::Request.new(env)["foo"] = "bar"  # sticks around for one request

  env["rack.session"] ||= {}
  env["rack.session"]["hello"] = "world" # sticks around for duration of session
end

# in Rails
def index
  if params["foo"] == "bar"
    ...
  end
  if session["hello"] == "world"
    ...
  end
end
4

2 に答える 2

30

Rack::Requestリクエストスコープ変数を渡すためにオブジェクトを使用できると確信しています:

# middleware:
def call(env)
  request = Rack::Request.new(env) # no matter how many times you do 'new' you always get the same object
  request[:foo] = 'bar'
  @app.call(env)
end

# Controller:
def index
  if params[:foo] == 'bar'
    ...
  end
end

envまたは、その " " オブジェクトを直接取得することもできます:

# middleware:
def call(env)
  env['foo'] = 'bar'
  @app.call(env)
end

# controller:
def index
  if request.env['foo'] == 'bar'
    ...
  end
end
于 2009-05-11T21:33:44.840 に答える
27

簡単な答え:request.envまたはenvコントローラー内で使用します。

長い答え:

Rails コントローラに関する Rails ガイド によると、 ActionController は、requestコントローラが応答している現在の HTTP リクエストに関する情報にアクセスするために使用できるメソッドを提供します。

のドキュメントをさらに調べると、ActionController::Base#request「現在のリクエストを表す ActionDispatch::Request インスタンスを返す」ことがわかります。

のドキュメントActionDispatch::Requestを見ると、 から継承されていることがわかりますRack::Request。あはは!どうぞ。

のドキュメントに慣れていない方Rack::Requestのために説明すると、これは基本的に Rack 環境のラッパーです。したがって、ほとんどの場合、そのまま使用できるはずです。ただし、生の環境ハッシュが本当に必要な場合は、 で取得できますRack::Request#env。したがって、Rails コントローラー内では、それは単にrequest.env.

より深く掘り下げる:

のインスタンス メソッドをさらに調べたところ、ActionController::Base見るべきものがあまりないことに気付きました。params特に、変数とsession変数が欠落しているように見えることに気付きました。そのため、1 レベル上に移動しActionController::Metal、 をActionController::Base継承しています。

で、私はそれが何をするかについて文書化されていないActionController::Metal方法を発見しました - しかし、私は推測することができました. env私が正しかったことがわかりました。その変数はに割り当てられていましたrequest.env

ActionController::Metalソースによると、デフォルトでに設定されていたparamsメソッドも含まれていました。結局のところ、からではなく、に含まれているActionDispatch::Http::Parametersです。このメソッドは メソッドと非常に似ていますが、変更すると Rails 固有の Rack 環境変数が変更される点が異なります (したがって、変更は のインスタンス間で永続化されます)。request.parametersrequest.parametersRack::RequestActionDispatch::RequestRack::Request#paramsActionDispatch::Request

しかし、私はまだ方法を見つけることができなかったようですsession。結局のところ、ドキュメントにはまったく記載されていません。のソースコードを検索した後ActionController::Metal、私は最終的にこの行にそれを見つけました。そうです、 request.sessionの単なるショートカットです。

要約する:

コントローラーで…

  • request.envorを使用envして生の環境オブジェクトを取得します
  • paramsラック クエリ文字列を読み取り、ラック入力ストリームからデータを投稿するために使用します。(例Rack::Request#params)
  • ラック環境でsessionの値にアクセスするために使用しますrack.session

ミドルウェアで...

于 2014-05-29T17:34:02.800 に答える