Search code examples
ruby-on-railsconventionsrackmiddleware

Where do you put your Rack middleware files and requires?


I'm in the process of refactoring some logic built into a Rails application into middleware, and one annoyance I've run into is a seeming lack of convention for where to put them.

Currently I've settled on app/middleware but I could just as easily move it to vendor/middleware or maybe vendor/plugins/middleware...

The biggest problem is having to require the individual files at the top of config/environment.rb

require "app/middleware/system_message"
require "app/middleware/rack_backstage"

or else I get uninitialized constant errors on the config.middleware.use lines. That could get messy very quickly. I'd rather this was tucked away in an initializer somewhere.

Is there a conventional place to put this stuff?


The specific answer I'm looking for with this bounty is: where can I put the require lines so that they are not cluttering the environment.rb file but still get loaded before the config.middleware.use calls? Everything I have tried leads to uninitialized constant errors.


Update: Now that we're using Rails 3.0, I treat a Rails app like any other Rack app; code files for middleware go in lib (or a gem listed in Gemfile) and are required and loaded in config.ru.


Solution

  • As of Rails 3.2, Rack middleware belongs in the app/middleware directory.

    It works "out-of-the-box" without any explicit require statements.

    Quick example:

    I'm using a middleware class called CanonicalHost which is implemented in app/middleware/canonical_host.rb. I've added the following line to production.rb (note that the middleware class is explicitly given, rather than as a quoted string, which works for any environment-specific config files):

    config.middleware.use CanonicalHost, "example.com"
    

    If you're adding middleware to application.rb, you'll need to include quotes, as per @mltsy's comment.

    config.middleware.use "CanonicalHost", "example.com"