Rails 内から Rack 環境にアクセスするにはどうすればよいですか?
-
21-08-2019 - |
質問
次のような Rack アプリケーションがあります。
class Foo
def initialize(app)
@app = app
end
def call(env)
env["hello"] = "world"
@app.call(env)
end
end
Rack アプリケーションを Rails にフックした後、どうすればアクセスできるようになりますか? env["hello"]
Rails内から?
アップデート:ガイウスさん、答えてくれてありがとう。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
解決
きっと使えると思います 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
他のヒント
短い答え: 使用 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
方法によると、 起源, 、に設定されました request.parameters
デフォルトでは。それが判明したとして、 request.parameters
からではありません Rack::Request
, 、 しかし ActionDispatch::Http::パラメータ, に含まれています。 ActionDispatch::Request
. 。この方法は、 Rack::Request#params
ただし、これを変更すると Rails 固有の Rack 環境変数が変更される点が異なります (したがって、変更はインスタンス間で永続的に残ります)。 ActionDispatch::Request
).
しかし、それでも見つからなかったようです session
方法。結局のところ、それはドキュメントにまったく記載されていません。ソースコードを検索した後、 ActionController::Metal
, 、やっと見つけました。 この行. 。そう、それはただのショートカットです リクエスト.セッション.
要約する:
コントローラーの中には…
- 使用
request.env
またはenv
生の環境オブジェクトを取得するには - 使用
params
Rack クエリ文字列を読み取り、Rack 入力ストリームからデータをポストします。(例えば。Rack::Request#params
) - 使用
session
の値にアクセスするにはrack.session
ラック環境で
ミドルウェアでは...
- 環境ハッシュを介して通常の方法で環境のプロパティにアクセスします
- Rails セッションにアクセスするには、
rack.session
環境ハッシュのプロパティ - パラメータを読み込む
Rack::Request#params
- パラメータを更新します
Rack::Request#update_param
そしてRack::Request#delete_param
(ドキュメントに記載されているように)Rack::Request#params
) - Rails 固有の方法でパラメータを更新するには、次を使用します。
ActionDispatch::Http::Parameters#params
を通してActionDispatch::Request