How do I access the Rack environment from within Rails?

Michael Gundlach picture Michael Gundlach · May 11, 2009 · Viewed 25k times · Source

I have a Rack application that looks like this:

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

After hooking my Rack application into Rails, how do I get access to env["hello"] from within Rails?

Update: Thanks to Gaius for the answer. Rack and Rails let you store things for the duration of the request, or the duration of the 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

Answer

James A. Rosen picture James A. Rosen · May 11, 2009

I'm pretty sure you can use the Rack::Request object for passing request-scope variables:

# 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

Alternatively, you can get at that "env" object directly:

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

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