started rubyonrails rails getting and ruby-on-rails ruby rack middleware

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 o env 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 de rack.session en el entorno de rack

En el middleware ...