【问题标题】:How to add middleware in Rails 4.2 application如何在 Rails 4.2 应用程序中添加中间件
【发布时间】:2016-04-24 14:00:57
【问题描述】:

我正在努力学习Middlewares 并一直在练习如何在 Rails 应用程序中安装它。我关注了railscast

到目前为止,我已经实现了这些步骤:

1) 创建了一个新的Rails 4.2 应用程序,名为:Blog

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

【问题讨论】:

  • 尝试将您的代码与问题一起添加,这将有助于其他人更好地理解这一点。
  • 您是否尝试过要求application.rb 中的文件,例如:require_relative '../lib/response_timer'
  • 更新了问题。这个答案也帮助了我stackoverflow.com/a/24122424
  • 是的,根据我的回答,它正在工作。
  • 真的是你的答案??。 :) 一切顺利。

标签: ruby-on-rails ruby ruby-on-rails-4 rack-middleware


【解决方案1】:

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

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

以上应该对你有用。

【讨论】:

  • autoload_paths 不起作用 :( 如果我这样做 rails server 然后 uninitialized constant Blog::Application::ResponseTimer (NameError) 如果我这样做 rake middleware 然后 NameError: uninitialized constant Blog::Application::ResponseTimer
  • 注意,在 Rails 5+ 中,您不能再使用字符串作为中间件的名称。您需要使用正确的类名。此外,根据@rafaelfranca(Rails 核心)的说法,“中间件不能在应用程序中,因为它们无法重新加载。它们应该在 lib 中,如果你将它们放在 lib 中,require_relative 将起作用。” i> github.com/rails/rails/issues/25525#issuecomment-479941866
【解决方案2】:

我关注了这个答案:https://stackoverflow.com/a/24122424

我之前尝试过,但之前可能错过了一些东西。

在appliation.rb

require 'rails/all'
require_relative '../lib/response_timer'
module Blog
 class Application < Rails::Application
  ...
  config.middleware.use ResponseTimer
 end
end

【讨论】:

  • 您不必明确包含该文件,它是一个antipattern。
  • @RichPeck 我敢肯定你指出的是绝对正确的,但config.autoload_paths += Dir["#{config.root}/lib/**/"] 除了调用整个lib 文件夹之外,这条线不是在做同样的事情,而在给定的答案中只调用一个文件。你能解释一下吗?
  • 它会自动加载lib文件夹,所以你不需要在application.rb中显式调用你需要的文件。
猜你喜欢
  • 1970-01-01
  • 2012-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-03
  • 2015-08-31
相关资源
最近更新 更多