2

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

我知道我们可以把这些东西放在config/initializersor中application.rb。但是,我想在每个请求之前运行它。

4

3 回答 3

7

听起来像是 Rack 中间件的工作。您可以查看Rails on Rack 指南RailsCast了解详细信息。

所以在 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

检查其插入是否正常:

rake middleware

就是这样!

于 2013-09-16T14:50:19.940 回答
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.

于 2013-09-16T14:39:18.733 回答
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

上面的示例可能会根据您要执行的操作而改变。

于 2013-09-16T14:41:52.330 回答