How to add middleware in Rails 4.2 application
Asked Answered
V

2

6

I am trying to learn Middlewares and been practising how to mount it in the Rails application. I have followed the railscast

So far I have implemented these steps:

1) Created a new Rails 4.2 application called: Blog

2) Added a file in the lib folder named as response_timer.rb.

class ResponseTimer
  def initialize(app)
    @app = app
  end

  def call(env)
    [200, {"Content-Type" => "text/html"}, "Hello World"]
  end
end

3) Added config.middleware.use "ResponseTimer" in application.rb.

config.middleware.use "ResponseTimer"

But as i'm hitting the command rake middleware in the terminal, it is reporting this error:

rake aborted!
NameError: uninitialized constant ResponseTimer

I tried also to add the config.middleware.use "ResponseTimer" in the development.rb but again facing the same error.

What am i missing here?

Please help.

Referenced article: http://guides.rubyonrails.org/rails_on_rack.html

Vedis answered 19/1, 2016 at 7:36 Comment(6)
try adding your code along with the question, that will be helpful for others to understand this better.Juan
have you tried requiring the file in application.rb, ex: require_relative '../lib/response_timer'Juan
Updated the question. Also this answer helped me stackoverflow.com/a/24122424Vedis
Yes as per my answer it is working.Vedis
really your answer ??. :) all the best.Juan
Exactly not my answer. As I told I followed this answer: link :)Vedis
P
5

Middleware has to have an accompanying module / class, and needs to be loaded in the app before it can be referenced. The way to do this in Rails is with autoloading (lib files aren't autoloaded by default):

#config/application.rb
config.autoload_paths += Dir["#{config.root}/lib/**/"]
config.middleware.use "ResponseTimer"

The above should work for you.

Photocurrent answered 19/1, 2016 at 9:3 Comment(2)
autoload_paths is not working :( If I do rails server then uninitialized constant Blog::Application::ResponseTimer (NameError) And If I do rake middleware then NameError: uninitialized constant Blog::Application::ResponseTimer Vedis
Note, in Rails 5+ you can no longer use the String for the name of the middleware. You need to use the proper class name. Additionally, according to @rafaelfranca (Rails core), "middleware can't be in app because they can't be reloaded. They should be in lib and if you put them in lib, require_relative will work." github.com/rails/rails/issues/25525#issuecomment-479941866Transparent
V
-2

I followed this answer: https://stackoverflow.com/a/24122424

I tried it before but maybe missed something before.

In appliation.rb

require 'rails/all'
require_relative '../lib/response_timer'
module Blog
 class Application < Rails::Application
  ...
  config.middleware.use ResponseTimer
 end
end
Vedis answered 19/1, 2016 at 8:47 Comment(3)
You shouldn't have to include the file explicitly, it's an antipattern.Photocurrent
@RichPeck I am sure what you have pointed out is absolutely correct but config.autoload_paths += Dir["#{config.root}/lib/**/"] isn't this line doing the same stuff except its calling the entire lib folder where as in the given answer its just calling one file. can you please explain a bit.Juan
It's autoloading the lib folder, so you don't need to explicitly call the files you need in your application.rb.Photocurrent

© 2022 - 2024 — McMap. All rights reserved.