次のような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
リクエストスコープ変数を渡すために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 Guide on Rails controllers によると、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 :: Parameters からのものであり、 ActionDispatch::Request
に含まれています。このメソッドは Rack::Request#params
メソッドと非常に似ていますが、変更するとRails固有のRack環境変数が変更される点が異なります(したがって、変更は ActionDispatch::Request
のインスタンス間で永続的に維持されます)。
しかし、それでもsession
メソッドを見つけることができなかったようです。結局のところ、それはドキュメントにはまったく含まれていません。ソースコードで ActionController::Metal
を検索したところ、ついに この行 で見つかりました。そうです、それは request.session のショートカットにすぎません。
コントローラー内...
request.env
またはenv
を使用して、生の環境オブジェクトを取得しますparams
を使用して、ラッククエリ文字列を読み取り、ラック入力ストリームからデータを投稿します。 (例: Rack::Request#params
)rack.session
の値にアクセスするには、session
を使用しますミドルウェア内...
rack.session
プロパティを介してRailsセッションにアクセスしますRack::Request#params
を介してパラメータを読み取りますRack::Request#update_param
および Rack::Request#delete_param
を介してパラメーターを更新します( Rack::Request#params
のドキュメントに記載されています)ActionDispatch::Http::Parameters#params
から ActionDispatch::Request
を使用して、パラメータをRails特定の方法で更新します