ruby on rails - rubyonrails - ¿Cómo accedo al entorno Rack desde Rails?
ruby rack web server (2)
Estoy bastante seguro de que puede usar el objeto Rack::Request
para pasar variables de ámbito de solicitud:
# 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
Alternativamente, puede obtener ese objeto " env
" directamente:
# middleware:
def call(env)
env[''foo''] = ''bar''
@app.call(env)
end
# controller:
def index
if request.env[''foo''] == ''bar''
...
end
end
Tengo una aplicación de Rack que se ve así:
class Foo
def initialize(app)
@app = app
end
def call(env)
env["hello"] = "world"
@app.call(env)
end
end
Después de conectar mi aplicación de Rack a Rails, ¿cómo obtengo acceso a env["hello"]
desde Rails?
Actualización : Gracias a Gaius por la respuesta. Rack y Rails le permiten almacenar cosas durante la duración de la solicitud o la duración de la sesión:
# 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
Respuesta corta: use request.env
o env
dentro de un controlador.
Respuesta larga:
De acuerdo con la Guía de Rails en los controladores de Rails , ActionController proporciona un método de request
que puede utilizar para acceder a la información sobre la solicitud HTTP actual a la que está respondiendo su controlador.
Tras una inspección adicional de los documentos para la ActionController::Base#request
, vemos que "Devuelve una instancia ActionDispatch :: Request que representa la solicitud actual".
Si miramos los documentos para ActionDispatch::Request
, vemos que hereda de Rack::Request
. Jajaja Aquí vamos.
Ahora, en caso de que no esté familiarizado con los documentos de Rack::Request
, es básicamente un contenedor alrededor del entorno de Rack. Por lo tanto, para la mayoría de los casos, debería poder usarlo tal como está. Sin embargo, si realmente desea el hash de entorno sin formato, puede obtenerlo con Rack::Request#env
. Entonces, dentro del controlador de Rails, eso solo sería request.env
.
Cavar más profundo:
Después de examinar más a fondo los métodos de instancia de ActionController::Base
, noté que no hay mucho que ver. En particular, noté que los params
y las variables de session
parecen faltar. Entonces, ActionController::Metal
un nivel a ActionController::Metal
, del cual ActionController::Base
hereda.
En ActionController::Metal
, descubrí un método env
que no tenía documentación sobre lo que hizo, pero podía adivinar. Resulta que tenía razón. Esa variable estaba siendo asignada a request.env
.
ActionController::Metal
también contenía el método params
, que, según la fuente , se configuró en request.parameters
de forma predeterminada. Resulta que request.parameters
no es de Rack::Request
, sino de request.parameters , que está incluido en ActionDispatch::Request
. Este método es muy similar al método Rack::Request#params
, excepto que al modificarlo se modifica una variable de entorno de Rack específica de Rails (y, por lo tanto, los cambios seguirán siendo persistentes en todas las instancias de ActionDispatch::Request
).
Sin embargo, todavía no pude encontrar el método de la session
. Resulta que no está en la documentación en absoluto. Después de buscar el código fuente de ActionController::Metal
, finalmente lo encontré en esta línea . Así es, es sólo un acceso directo para request.session .
Para resumir:
En el controlador ...
- Utilice
request.env
oenv
para obtener el objeto de entorno sin procesar - Use
params
para leer cadenas de consulta de Rack y publicar datos de la secuencia de entrada del rack. (Por ejemplo,Rack::Request#params
) - Utilice la
session
para acceder al valor derack.session
en el entorno de rack
En el middleware ...
- Acceda a las propiedades del entorno de la forma habitual a través del hash del entorno.
- Acceda a la sesión de Rails a través de la propiedad
rack.session
en el hash del entorno - Lee params a través de
Rack::Request#params
- Actualice los parámetros a través de
Rack::Request#update_param
yRack::Request#delete_param
(como se indica en los documentos paraRack::Request#params
) - Actualice los parámetros de una manera específica de Rails usando
ActionDispatch::Http::Parameters#params
través deActionDispatch::Request