Daniel Rikowski
Daniel Rikowski

Reputation: 72504

How to access specific instances of the Rack middlewares?

In my Rails 3.2 application I have to call a method on a middleware instance of a certain class type.

I tried to use Rails.application.middleware but that doesn't work because it only wraps the middleware classes and not their instances.

Right now I'm walking the middleware chain starting from Rails.application.app using Ruby's instance_variable_get and is_a?, but that doesn't feel right, especially because there is no specified way a middleware stores the context. For example Rack::Cache::Context stores the next instance in a variable called @backend while most others use @app.

Is there a better way to find a middleware instance?

Upvotes: 5

Views: 1158

Answers (1)

Catnapper
Catnapper

Reputation: 1905

You could have the middleware add itself to the rack environment, as in this example:

require 'rack'

class MyMiddleware
  attr_accessor :add_response
  def initialize app
    @app = app
  end
  def call env
    env['my_middleware'] = self # <-- Add self to the rack environment
    response = @app.call(env)
    response.last << @add_response
    response
  end
end

class MyApp
  def call env
    env['my_middleware'].add_response = 'World!' # <-- Access the middleware instance in the app
    [200, {'Content-Type'=>'text/plain'}, ['Hello']]
  end
end

use MyMiddleware
run MyApp.new

Upvotes: 6

Related Questions