Pergunta

Eu tenho uma aplicação Rack que se parece com isso:

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

Depois de ligar a minha aplicação Rack em Rails, como faço para obter acesso a env["hello"] de dentro Rails?

Atualizar : Graças a Caio para a resposta. Rack e Rails permitem armazenar coisas para a duração do pedido, ou a duração da sessão:

# 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
Foi útil?

Solução

Eu tenho certeza que você pode usar o objeto Rack::Request para passar variáveis ??pedido de escopo:

# 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

Como alternativa, você pode obter naquele objeto "env" diretamente:

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

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

Outras dicas

Resposta curta:. Use request.env ou env dentro de um controlador

Resposta longa:

De acordo com a Guia do Rails on Rails controladores , ActionController fornece uma método request que você pode usar para acessar informações sobre a solicitação HTTP atual controlador está respondendo a.

Após uma inspecção mais aprofundada dos documentos para ActionController::Base#request , vemos que ela "Retorna uma instância ActionDispatch :: Request que representa a solicitação atual."

Se olharmos para os documentos para ActionDispatch::Request , vemos que ele herda de Rack::Request . Aha! Aqui vamos nós.

Agora, no caso de você não estiver familiarizado com a documentação para Rack::Request , é basicamente um invólucro em torno do ambiente rack. Assim, para a maioria dos casos, você deve apenas ser capaz de usá-lo como está. Se você realmente quer o hash ambiente crua, porém, você pode obtê-lo com Rack::Request#env . Então, dentro do controlador Rails, que seria apenas request.env.

Indo mais fundo:

Depois de examinar ainda mais os métodos de instância de ActionController::Base , notei que não é um lote inteiro lá para olhar. Em particular, eu notei a params e variáveis ??session parecem estar faltando. Então, eu me mudei para um nível acima para ActionController::Metal , que ActionController::Base herda a partir

Na ActionController::Metal , eu descobri um método env que não tinha documentação, como o que ele fez - mas eu podia adivinhar. Acontece que eu estava certo. Essa variável foi sendo atribuído a request.env .

ActionController::Metal também continha o params método, que, de acordo com a fonte , foi definido como request.parameters por padrão. Como se vê, request.parameters não é de Rack::Request , mas ActionDispatch :: Http :: Parâmetros , que é incluído por ActionDispatch::Request. Este método é muito semelhante ao método Rack::Request#params , salvo que a alteração modifica uma variável ambiente cremalheira específicos de carris (e, por conseguinte, muda permanecerá persistente entre instâncias de ActionDispatch::Request ).

No entanto, eu ainda podia não parecem encontrar o método session. Acontece que, não é na documentação em tudo. Depois de pesquisar o código fonte para ActionController::Metal , eu finalmente encontrei-o em esta linha . É isso mesmo, é apenas um atalho para request.session .

Para resumir:

No controlador ...

  • Use request.env ou env para chegar ao objeto ambiente cru
  • Use params para ler seqüências de consulta da cremalheira e postar dados do fluxo de entrada rack. (Por exemplo Rack::Request#params )
  • Use session para acessar o valor de rack.session no ambiente cremalheira

No middleware ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top