我想在每个请求之前在rails app中运行一段代码。此外,它应该在达到application_controller.rb
之前运行。
我知道我们可以将这些内容放在config/initializers
或application.rb
中。但是,我想在每次请求之前运行它。
答案 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 Guide和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
检查是否插入了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。
上述示例可能会根据您的操作而改变。