Rails在application.rb之前的每个请求之前运行代码

时间:2013-09-16 14:28:32

标签: ruby-on-rails ruby-on-rails-3

我想在每个请求之前在rails app中运行一段代码。此外,它应该在达到application_controller.rb之前运行。

我知道我们可以将这些内容放在config/initializersapplication.rb中。但是,我想在每次请求之前运行它。

3 个答案:

答案 0 :(得分:6)

你想写一些Rack Middleware。这很容易,这是一个简单的例子,它为多租户范围的目的获取子域名:

class ClientSetup
  def initialize(app)
    @app = app
  end

  def call(env)
    @request = Rack::Request.new(env)
    Multitenant.current_tenant = Tenant.find_by_subdomain!(get_subdomain)
    @app.call(env)
  end

  private
    def get_subdomain
      host = @request.host
      return nil unless !(host.nil? || /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.match(host))
      subdomain = host.split('.')[0..-3].first
      return subdomain unless subdomain == "www"
      return host.split('.')[0..-3][1]
    end
end

周围有更多的例子。然后,您需要使用以下命令将此类添加到中间件堆栈中:

config.middleware.use 'ClientSetup'

application.rb

答案 1 :(得分:6)

听起来像Rack中间件的工作。您可以查看Rails on Rack GuideRailsCast了解详情。

所以在lib中添加如下内容:

#lib/my_app_middleware.rb
class MyAppMiddleware
  def initialize(app)
    @app = app
  end

  def call(env)
    # place the code that you want executed on every request here
  end
end

以下在config / application.rb中启用中间件

config.middleware.use MyAppMiddleware

检查是否插入了ok:

rake middleware

多数民众赞成!

答案 2 :(得分:2)

它通常是ApplicationController的子类,在将调度路由到您的某个操作时会被调用。话虽这么说,如果你真的想在控制器被调用之前执行代码(在before_filters之前等),那么你可以修改Rails中的中间件链,如下所示:

config.middleware.insert_after(Rails::Rack::Logger, MyCustomMiddlewareClass)

您可以在此处阅读以获取更多信息:http://guides.rubyonrails.org/rails_on_rack.html#action-dispatcher-middleware-stack

上述示例可能会根据您的操作而改变。