Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 4 向Rails 4添加自定义中间件_Ruby On Rails 4_Rack_Rack Middleware - Fatal编程技术网

Ruby on rails 4 向Rails 4添加自定义中间件

Ruby on rails 4 向Rails 4添加自定义中间件,ruby-on-rails-4,rack,rack-middleware,Ruby On Rails 4,Rack,Rack Middleware,我有一个Rails 4示例项目(Blog),我在config/initializers/request\u timer.rb #config/initializers/request_timer.rb class RequestTimer

我有一个Rails 4示例项目(Blog),我在
config/initializers/request\u timer.rb

  #config/initializers/request_timer.rb
  class RequestTimer                                                                                                                                         

    def initialize(app)                                                                                                                                      
     @app = app                                                                                                                                              
    end                                                                                                                                                      

    def call(env)                                                                                                                                            
      start_time = Time.now                                                                                                                                  
      status, headers, response = @app.call(env)                                                                                                             
      stop_time = Time.now                                                                                                                                   
      [status, headers, response.body]                                                                                                                       
    end                                                                                                                                                      

  end 
我以两种方式在
config/application.rb
中添加了中间件

1)作为常量添加

#config/application.rb
module Blog                                                                                                                                                  
  class Application < Rails::Application                                                                                                                     
    config.middleware.use RequestTimer                                                                                                                       
  end                                                                                                                                                        
end
原因是什么?我正在使用Rails
4.0.2
rack-1.5.2
ruby 2.0.0p247

  • config/initializers/request_timer.rb
    移动到
    lib/request_timer.rb
    文件夹
  • require\u relative'../lib/request\u timer'
    行添加到
    application.rb
    文件中
  • config.middleware.use“RequestTimer”更改为
    config.middleware.use RequestTimer
    。不要使用引号 我记得,如果不在
    application.rb
    ,我们就不能使用initializers文件夹中的类

    关于。

    NoMethodError(未定义的方法'each'for#)
    ,您应该确保
    response.body
    响应'each'方法,但其类是字符串。您可以这样修复代码:
    [状态,标题,[response.body]

    Ruby 1.9不再在String类中使用每个

    要使用Rack,请提供一个“app”:一个响应调用方法的对象,将环境散列作为参数,并返回一个包含三个元素的数组:
    *HTTP响应代码
    *标题的散列
    *响应主体,必须对每个
    进行响应


    解决这个问题更简单的方法是将您的
    请求\u timer.rb
    放入
    app/middleware/request\u timer.rb
    ,然后将中间件作为字符串添加到
    config/application.rb

    中。您应该将中间件类放在app/middleware文件夹中。添加的中间件应注入rails默认添加的中间件列表中

    注意:您可以从代码中的任何位置插入中间件,但最好在为应用程序添加的任何初始值设定项中插入中间件

    例如,要在rails内置中间件params解析器之后插入中间件,请执行以下操作:

    Rails.application.middleware.insert_after ActionDispatch::ParamsParser, "RequestTimer"
    
    此外,您还可以向中间件传递所需的参数,例如:

    options = { :foo => 'bar' }
    Rails.application.middleware.insert_after ActionDispatch::ParamsParser, "SecuredClient", options
    
    然后,您可以在中间件中访问这些参数,如下所示:

    class RequestTimer                                                                                                                                         
      def initialize(app, params)                                                                                                                                      
        @app = app
        @params = params                                                                                          
      end
    end
    

    谢谢@onurozgurozkhan!我想这取决于Rails的版本。对于Rails 3.x,我使用了def call(env)@app.call env end这是Rails 5+的绝对正确答案。以下是与Rails core的相关讨论:@memoht你为什么对我的答案投反对票?它已被弃用,但在rails 5中。问题是关于rails 4!你说得对。我删除了我的评论,如果允许的话,我将删除否决票。在答案中添加这样一个事实,即Rails 5中不推荐使用此选项将非常有用。注意,在Rails 5+中,您不能再使用字符串作为中间件的名称。您需要使用正确的类名。此外,根据@rafaelfranca(Rails core),“中间件不能在应用程序中,因为它们不能被重新加载。它们应该在lib中,如果你把它们放在lib中,require_relative将起作用。”注意,在Rails 5+中,你不能再使用字符串作为中间件的名称。您需要使用正确的类名。此外,根据@rafaelfranca(Rails核心)的说法,“中间件不能在应用程序中,因为它们不能被重新加载。它们应该在lib中,如果你把它们放在lib中,require_relative就会工作。”
    Rails.application.middleware.insert_after ActionDispatch::ParamsParser, "RequestTimer"
    
    options = { :foo => 'bar' }
    Rails.application.middleware.insert_after ActionDispatch::ParamsParser, "SecuredClient", options
    
    class RequestTimer                                                                                                                                         
      def initialize(app, params)                                                                                                                                      
        @app = app
        @params = params                                                                                          
      end
    end