Domanda

Ho un'applicazione Rack che assomiglia a questo:

class Foo
  def initialize(app)
    @app = app
  end
  def call(env)
    env["hello"] = "world"
    @app.call(env)
  end
end

Una volta collegati mia applicazione Rack in Rails, come faccio a accesso a env["hello"] dall'interno Rails?

Aggiorna : Grazie a Caio per la risposta. Rack e Rails consentono di memorizzare le cose per tutta la durata della richiesta, o la durata della sessione:

# 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
È stato utile?

Soluzione

Sono abbastanza sicuro che è possibile utilizzare l'oggetto Rack::Request per il passaggio di variabili di richiesta-scope:

# 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

In alternativa, è possibile ottenere in quel "env" oggetto direttamente:

# middleware:
def call(env)
  env['foo'] = 'bar'
  @app.call(env)
end

# controller:
def index
  if request.env['foo'] == 'bar'
    ...
  end
end

Altri suggerimenti

Risposta breve: Usa request.env o env dentro un controllore

.

Risposta lunga:

Secondo il Guida Rails on Rails controller , ActionController fornisce un request metodo che è possibile utilizzare per accedere alle informazioni relative alla richiesta HTTP corrente il controller risponde a.

Ulteriori controlli dei documenti per ActionController::Base#request , vediamo che "restituisce un ActionDispatch :: un'istanza richiesta che rappresenta la richiesta di corrente".

Se guardiamo la documentazione per ActionDispatch::Request , vediamo che eredita da Rack::Request . Aha! Qui andiamo.

Ora, nel caso in cui non hai familiarità con la documentazione per < => , è fondamentalmente un wrapper per l'ambiente rack. Quindi, per la maggior parte dei casi, si dovrebbe solo essere in grado di usarlo così com'è. Se davvero si vuole l'ambiente hash grezzo, però, si può ottenere con Rack::Request#env . Così all'interno del controller Rails, che sarebbe solo ActionController::Base.

Scavando più a fondo:

Dopo aver esaminato ulteriormente i metodi di params , ho notato che c'è istanze non un bel po 'lì a guardare. In particolare, ho notato la session e ActionController::Metal variabili sembrano mancare. Così, mi sono spostato di un livello a request.parameters , che Rack::Request#params eredita da.

rack.session , ho scoperto un metodo di Rack::Request#update_param che aveva privi della documentazione di quello che ha fatto - ma ho potuto indovina. Venuto fuori che avevo ragione. Tale variabile è stata essere assegnato a Rack::Request#delete_param .

ActionDispatch::Http::Parameters#params conteneva anche il <=> metodo, che, secondo la fonte , è stato impostato su <=> per impostazione predefinita. Come si è visto, non è <=> da <=> , ma ActionDispatch :: HTTP :: Parametri , che è incluso da <=> . Questo metodo è molto simile al metodo <=> , tranne che l'alterazione si modifica una variabile ambiente Rack Rails-specifica (e quindi variazioni rimarrà persistente di tutti istanze di <=> ).

Tuttavia, ho ancora potuto non sembrano trovare il metodo <=>. Si scopre, non è nella documentazione a tutti. Dopo la ricerca il codice sorgente per <=> , finalmente ho trovato su questa linea . Proprio così, è solo una scorciatoia per request.session .

Per riassumere:

Nel controllore ...

  • Usa <=> o <=> per ottenere l'oggetto ambiente grezzo
  • Usa <=> per leggere stringhe di query rack e POST dati dal flusso di input rack. (Ad esempio <=> )
  • Usa <=> per accedere al valore della <=> in ambiente rack

Nel middleware ...

  • le proprietà di accesso dell'ambiente come di consueto attraverso l'hash ambiente
  • Accedi alla sessione Rails attraverso il <=> proprietà sul hash ambiente
  • Leggi params attraverso <=>
  • Aggiornamento params attraverso <=> e < a href = "http://rubydoc.info/github/rack/rack/master/Rack/Request#delete_param-instance_method" rel = "noreferrer"> <=> (come indicato nella documentazione per <=> )
  • Aggiornamento params in modo specifico Rails utilizzando <= > attraverso <=>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top