我想在每次请求之前在 rails 应用程序中运行一段代码。此外,它应该在到达之前运行application_controller.rb
。
我知道我们可以把这些东西放在config/initializers
or中application.rb
。但是,我想在每个请求之前运行它。
我想在每次请求之前在 rails 应用程序中运行一段代码。此外,它应该在到达之前运行application_controller.rb
。
我知道我们可以把这些东西放在config/initializers
or中application.rb
。但是,我想在每个请求之前运行它。
听起来像是 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
就是这样!
你会想写一些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
.
它通常是 ApplicationController 的一个子类,当路由调度到您的一个操作时会被调用。话虽如此,如果您真的想在调用控制器之前(在 before_filters ... 等之前)执行代码,那么您可以像这样修改 Rails 中的中间件链:
config.middleware.insert_after(Rails::Rack::Logger, MyCustomMiddlewareClass)
你可以在这里阅读更多信息: http: //guides.rubyonrails.org/rails_on_rack.html#action-dispatcher-middleware-stack。
上面的示例可能会根据您要执行的操作而改变。