Comment puis-je accéder à l'environnement de rack à l'intérieur Rails?
-
21-08-2019 - |
Question
J'ai une application de rack qui ressemble à ceci:
class Foo
def initialize(app)
@app = app
end
def call(env)
env["hello"] = "world"
@app.call(env)
end
end
Après avoir raccordé mon application Rails rack dans, comment puis-je avoir accès à l'intérieur Rails env["hello"]
?
Mise à jour : Merci à Gaius pour la réponse. Rack et Rails vous permettent de stocker des choses pendant toute la durée de la demande, ou la durée de la session:
# 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
La solution
Je suis sûr que vous pouvez utiliser l'objet pour passer des variables Rack::Request
-champ d'application de la demande:
# 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
Vous pouvez obtenir à cet objet « env
» directement:
# middleware:
def call(env)
env['foo'] = 'bar'
@app.call(env)
end
# controller:
def index
if request.env['foo'] == 'bar'
...
end
end
Autres conseils
Réponse courte: Utilisez ou request.env
dans un contrôleur env
Réponse longue:
Selon le rails de guidage sur les contrôleurs Rails , ActionController fournit une méthode que vous request
pouvez utiliser pour accéder à des informations sur la requête HTTP actuelle de votre contrôleur répond à.
Après vérification de la documentation pour ActionController::Base#request
, on voit que « Retourne un ActionDispatch :: instance de demande qui représente la demande actuelle. »
Si l'on regarde la documentation pour ActionDispatch::Request
, nous voyons que il hérite de Rack::Request
. Aha! nous allons ici.
Maintenant, si vous n'êtes pas familier avec la documentation pour < => , il est essentiellement une enveloppe autour de l'environnement du rack. Donc, pour la plupart des cas, vous devriez juste pouvoir l'utiliser tel quel. Si vous ne voulez vraiment le hachage de l'environnement cru bien, vous pouvez l'obtenir avec Rack::Request#env
. Ainsi, dans le contrôleur Rails, ce serait juste ActionController::Base
.
Creuser plus profond:
Après avoir examiné davantage les méthodes d'instance de params
, j'ai remarqué qu'il ya pas beaucoup là pour regarder. En particulier, j'ai remarqué et session
les variables semblent ActionController::Metal
manquer. Alors, je me suis déplacé d'un niveau request.parameters
, qui Rack::Request#params
hérite de.
rack.session
, j'ai découvert une méthode Rack::Request#update_param
qui avait aucun document à ce qu'il a fait - mais je ne pouvais devine. Il se trouve que j'avais raison. Cette variable a été étant affecté à Rack::Request#delete_param
.
contenait également ActionDispatch::Http::Parameters#params
méthode <=> , qui, selon source, a été mis à <=> par défaut. Comme il se trouve, est pas de <=> <=> , mais ActionDispatch :: Http :: Paramètres , qui est inclus par <=>. Cette méthode est très similaire à la méthode <=> , sauf que la modification modifie une variable d'environnement rack spécifique à Rails (et donc des changements restera persistante dans les instances de <=> ).
Cependant, je ne pouvais toujours pas à trouver la méthode <=>. Il s'avère, ce n'est pas dans la documentation du tout. Après avoir cherché le code source <=>, je l'ai enfin trouvé sur cette ligne . C'est vrai, il est juste un raccourci pour request.session .
Pour résumer:
Dans le contrôleur ...
- Utilisez ou <=> pour obtenir à <=> l'objet de l'environnement brut
- Utiliser <=> pour lire les chaînes de requête à la rampe et les données de poste à partir du courant d'entrée de l'armoire. (Par ex <=>)
- Utilisation <=> pour accéder à la valeur de <=> dans l'environnement de l'armoire
Dans le middleware ...
- propriétés d'accès de l'environnement de la façon habituelle par le hachage de l'environnement
- Accédez à la session Rails par la propriété sur le <=> hachage environnement
- Lire params par <=>
- Mise à jour params par et <=> < a href = "http://rubydoc.info/github/rack/rack/master/Rack/Request#delete_param-instance_method" rel = "noreferrer"> <=> (comme indiqué dans la documentation pour <=> )
- Mise à jour params de manière spécifique Rails en utilisant <= > par <=>