如何在Rails 4.2应用程序中添加中间件

6
我正在尝试学习Middlewares,并练习如何在Rails应用程序中挂载它。我已经遵循了railscast
到目前为止,我已经实施了以下步骤:
1)创建了一个名为Blog的新Rails 4.2应用程序
2)在lib文件夹中添加了一个名为response_timer.rb的文件。
class ResponseTimer
  def initialize(app)
    @app = app
  end

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

3) 在 application.rb 中添加了 config.middleware.use "ResponseTimer"

config.middleware.use "ResponseTimer"

但是当我在终端中输入命令rake middleware时,它报告了这个错误:

rake aborted!
NameError: uninitialized constant ResponseTimer

我也尝试在development.rb中添加config.middleware.use "ResponseTimer",但仍然遇到相同的错误。

我错过了什么吗?

请帮忙。

参考文章: http://guides.rubyonrails.org/rails_on_rack.html


尝试在问题中添加您的代码,这将有助于其他人更好地理解。 - Abhinay
你尝试过在 application.rb 中引用文件吗?例如:require_relative '../lib/response_timer' - Abhinay
更新了问题。此外,这个回答对我很有帮助 https://dev59.com/zOo6XIcBkEYKwwoYKRDG#24122424 - Hashmita Raut
是的,根据我的回答它正在工作。 - Hashmita Raut
你真的确定这是你的答案吗? :) 祝一切顺利。 - Abhinay
不是我的答案。正如我所说,我遵循了这个答案:链接 :) - Hashmita Raut
2个回答

5

中间件必须有一个相应的模块/类,并且需要在应用程序中加载后才能被引用。在Rails中完成这个操作的方法是使用autoloading(默认情况下不会自动加载lib文件):

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

以上方法适用于您。

2
autoload_paths 不起作用 :( 如果我运行 rails server,则会出现 uninitialized constant Blog::Application::ResponseTimer (NameError) 的错误。如果我运行 rake middleware,则会出现 NameError: uninitialized constant Blog::Application::ResponseTimer 的错误。 - Hashmita Raut
注意,在Rails 5+中,您不能再使用字符串作为中间件的名称。您需要使用正确的类名。此外,根据@rafaelfranca(Rails核心)的说法,“中间件不能在应用程序中,因为它们无法重新加载。它们应该在lib中,如果您将它们放在lib中,require_relative将起作用。” https://github.com/rails/rails/issues/25525#issuecomment-479941866 - Joshua Pinter

-2
我按照这个答案:https://dev59.com/zOo6XIcBkEYKwwoYKRDG#24122424 进行操作。
我之前尝试过,但可能漏掉了一些步骤。
appliation.rb中。
require 'rails/all'
require_relative '../lib/response_timer'
module Blog
 class Application < Rails::Application
  ...
  config.middleware.use ResponseTimer
 end
end

你不应该显式地包含文件,这是一种反模式。 - Richard Peck
@RichPeck,我相信你指出的是绝对正确的,但是config.autoload_paths += Dir["#{config.root}/lib/**/"]这行代码不是在做同样的事情吗?只不过它调用了整个lib文件夹,而在给出的答案中只调用了一个文件。你能解释一下吗? - Abhinay
它正在自动加载lib文件夹,因此您不需要在application.rb中显式调用所需的文件。 - Richard Peck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接