带有rails 3的Hello World机架中间件:如何处理所有请求的主体

Han*_*bes 5 rack middleware rack-middleware ruby-on-rails-3

我想尝试一个简单的机架中间件"hello world",但我似乎陷入困境.看起来主要的sytax发生了变化,因为一些例子使用了这段代码:

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
Run Code Online (Sandbox Code Playgroud)

产生错误:

undefined method `<<' for #<ActionDispatch::Response:0x103f07c48>
Run Code Online (Sandbox Code Playgroud)

即使我看到那里的其他代码,我似乎无法使用rails 3.0.3运行它们.

这是我的具体问题:

  • 我怎么能得到一个简单的机架中间件来运行和修改rails应用程序的任何输出的主体?
  • 我应该把Rails.application.config.middleware.use声明放在哪里?(我在配置/初始化器中创建了一个自己的初始化器)

非常感谢!

Uni*_*key 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
Run Code Online (Sandbox Code Playgroud)

请注意,几乎所有其他请求(至少在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

当然官方机架规格:

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


zed*_*xff 6

Rails 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
Run Code Online (Sandbox Code Playgroud)