6

我想尝试一个简单的机架中间件“hello world”,但我似乎卡住了。看起来主语法发生了变化,因为一些示例使用以下代码:

require 'rack/utils'

class FooBar

  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, body = @app.call(env)
         body.body << "\nHi from #{self.class}"
         [status, headers, body]
  end
end

产生错误:

undefined method `<<' for #<ActionDispatch::Response:0x103f07c48>

即使我查看那里的其他代码,我似乎也无法让它们与 rails 3.0.3 一起运行。

这是我的具体问题:

  • 如何获得一个简单的机架中间件来运行和修改 Rails 应用程序的任何输出的主体?
  • 我应该把 Rails.application.config.middleware.use 声明放在哪里?(为此,我在 config/initializers 中创建了一个自己的初始化程序)

提前非常感谢!

4

2 回答 2

6

导轨3.2.12+

以前的答案不适用于 Rails 3.2.12+

这个可以:

# in config/application.rb
config.middleware.use 'FooBar'

# in config/initializers/foo_bar.rb
class FooBar
  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, response = @app.call(env)
    response.body += "\nHi from #{self.class}"
    # response.body << "..." WILL NOT WORK
    [status, headers, response]
  end
end
于 2013-04-02T21:35:05.863 回答
6

这应该做你想做的事:

# in config/application.rb
config.middleware.use 'FooBar'

# in config/initializers/foo_bar.rb
class FooBar
  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, response = @app.call(env)
    [status, headers, response.body << "\nHi from #{self.class}"]
  end
end

请注意,对于几乎所有其他请求(至少在 Rails 3.0.3 上),这将由于另一个中间件(Rack::Head)而失败,因为它在内容未更改时发送一个空请求。我们在这个例子中依赖于能够调用 response.body,但实际上,数组的最后一个成员可以是响应 .each 的任何东西。

Ryan Bates 在这里很好地介绍了 Rack:

http://asciicasts.com/episodes/151-rack-middleware

http://railscasts.com/episodes/151-rack-middleware

Rails 官方指南也很不错:

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

当然还有官方 Rack 规格:

http://rack.rubyforge.org/doc/SPEC.html

于 2011-04-06T02:08:18.860 回答