- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
Rails 版本:'~> 4.2.7.1'
spree 版本:'3.1.1'
提示:我如何获得 /api/products/:id
的路线或在 Rails 4 应用程序的中间件中该路由的 Controller 和操作。
我正在我的 Rails 应用程序中添加一个类似于 gem scout_statsd_rack 的中间件.这将添加以下 middleware到 Rails 应用程序以通过 statsd 发送指标:
def call(env)
(status, headers, body), response_time = call_with_timing(env)
statsd.timing("#{env['REQUEST_PATH']}.response", response_time)
statsd.increment("#{env['REQUEST_PATH']}.response_codes.#{status.to_s.gsub(/\d{2}$/,'xx')}")
# Rack response
[status, headers, body]
rescue Exception => exception
statsd.increment("#{env['REQUEST_PATH']}.response_codes.5xx")
raise
end
def call_with_timing(env)
start = Time.now
result = @app.call(env)
[result, ((Time.now - start) * 1000).round]
end
我想要的是在中间件中找到当前路由,以便我可以发送特定于每个路由的指标。
我尝试了描述的方法 here ,它告诉 env['PATH_INFO']
可以提供路径,它确实提供了路径,但它提供了这样的 URL 参数:/api/products/4
但我想要的是 /api/products/:id
因为我的目的是跟踪 /api/products/:id
的性能API。
env['REQUEST_PATH']
和 env['REQUEST_URI']
也给出了相同的响应。
Rails.application.routes.router.recognize({"path_info" => env['PATH_INFO']})
或者像这样
Rails.application.routes.router.recognize(env['PATH_INFO'])
但它给出了以下错误:
NoMethodError (undefined method
path_info' for {"path_info"=>"/api/v1/products/4"}:Hash):<br/>
find_routes'
vendor/bundle/gems/actionpack-4.2.7.1/lib/action_dispatch/journey/router.rb:100:in
vendor/bundle/gems/actionpack-4.2.7.1/lib/action_dispatch/journey/router.rb:59:inrecognize'<br/>
call'
vendor/bundle/gems/scout_statsd_rack-0.1.7/lib/scout_statsd_rack.rb:27:in
这answer讨论 request.original_url
, 但如何访问变量 request
, 我认为它应该与 env
相同但无法从中获得所需的路线。
您可以查看示例存储库 here , 带有 rails 中间件的代码 here , 可以按照 README 中的说明进行设置然后可以点击此 API:http://localhost:3000/api/v1/products/1
.
我尝试了@MichałMłoźniak 给出的方法,如下所示:
def call(env)
(status, headers, body), response_time = call_with_timing(env)
request = ActionDispatch::Request.new(env)
request = Rack::Request.new("PATH_INFO" => env['REQUEST_PATH'], "REQUEST_METHOD" => env["REQUEST_METHOD"])
Rails.application.routes.router.recognize(request) { |route, params|
puts "I am here"
puts params.inspect
puts route.inspect
}
但我得到了以下回复:
I am here
{}
#<ActionDispatch::Journey::Route:0x007fa1833ac628 @name="spree", @app=#<ActionDispatch::Routing::Mapper::Constraints:0x007fa1833ace70 @dispatcher=false, @app=Spree::Core::Engine, @constraints=[]>, @path=#<ActionDispatch::Journey::Path::Pattern:0x007fa1833acc90 @spec=#<ActionDispatch::Journey::Nodes::Slash:0x007fa1833ad230 @left="/", @memo=nil>, @requirements={}, @separators="/.?", @anchored=false, @names=[], @optional_names=[], @required_names=[], @re=/\A\//, @offsets=[0]>, @constraints={:required_defaults=>[]}, @defaults={}, @required_defaults=nil, @required_parts=[], @parts=[], @decorated_ast=nil, @precedence=1, @path_formatter=#<ActionDispatch::Journey::Format:0x007fa1833ac588 @parts=["/"], @children=[], @parameters=[]>>
我也推送了更改here .
最佳答案
您需要将ActionDispatch::Request
或Rack::Request
传递给recognize
方法。这是另一个应用程序的示例:
main:0> req = Rack::Request.new("PATH_INFO" => "/customers/10", "REQUEST_METHOD" => "GET")
main:0> Rails.application.routes.router.recognize(req) { |route, params| puts params.inspect }; nil
{:controller=>"customers", :action=>"show", :id=>"10"}
=> nil
同样适用于 ActionDispatch::Request
。在中间件内部,您可以轻松创建此对象:
request = ActionDispatch::Request.new(env)
如果您需要有关已识别路线的更多信息,您可以通过 recognize
方法查看被阻止的路线对象。
更新
上面的解决方案适用于普通的 Rails 路由,但是由于你只安装了 spree 引擎,你需要使用不同的类
request = ActionDispatch::Request.new(env)
Spree::Core::Engine.routes.router.recognize(request) { |route, params|
puts params.inspect
}
我想最好的办法是找到一个适用于任何常规路线和引擎组合的通用解决方案,但这适用于您的情况。
更新 #2
对于更通用的解决方案,您需要查看 Rails 路由器的源代码,您可以在 ActionDispatch
模块中找到它。查看 Routing
和 Journey
模块。我发现可以测试从 recognize
方法返回的路由是否是调度程序。
request = ActionDispatch::Request.new(env)
Rails.application.routes.router.recognize(req) do |route, params|
if route.dispatcher?
# if this is a dispatcher, params should have everything you need
puts params
else
# you need to go deeper
# route.app.app will be Spree::Core::Engine
route.app.app.routes.router.recognize(request) do |route, params|
puts params.inspect
}
end
end
此方法适用于您的应用,但并不通用。例如,如果您安装了 sidekiq,route.app.app
将是 Sidekiq::Web
,因此需要以不同的方式处理它。基本上,要获得通用解决方案,您需要处理 Rails 路由器支持的所有可能的可安装引擎。
我想最好构建一个涵盖当前应用程序中所有案例的东西。所以要记住的是,当初始请求被识别时,route
的值 yield to black 可以是调度程序,也可以不是。如果是,则您有正常的 Rails 路由,如果不是,则需要递归检查。
关于ruby-on-rails - 如何在 Rails 中间件中查找当前抽象路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42691729/
有人可以给我一个更简单的以下代码的解决方案(它正在展开给定结构 0xFC :: len :: payload :: ... :: 0x0A :: 0x0D 的整数列表): object Payload
我已经在我的网站上安装了 SSL 证书,但 intermediate.crt 无法正常工作。任何 SSL 检查器(例如 GeoTrust Checker)都告诉我,缺少中间 key 。网站上已经使用了
如何让图像从这个框的中间开始? (中间纵横) 最佳答案 有几种方法可以做到这一点,如果它需要在所有浏览器(IE7+ 和其他浏览器)中工作,你需要做不同的事情来让它在某些情况下工作。 使用绝对位置
如何强制 min-height 和 vertical-align:middle 为 td 元素或其内部元素工作? 最佳答案 td 元素上的 height 等同于 min-height,因为如果需要,表
我正在尝试自动滚动到订单簿的中间行。 我有 orderBook div,其中放置了带有 orderBook 的表。该表的其中一行有一个 id middleRow。我想做的是滚动该行并将其放置在 ord
我正在尝试在 javascript 中计算绝对定位元素的 transform-origin 属性,以便它们在悬停时填充整个视口(viewport)。 我尝试通过 x 除以窗口宽度和 y 除以窗口高度来
我有休闲字符串 ' this is my string ' 是否可以删除开头和结尾的所有空格,只在单词之间留一个空格。 要选择我使用过的所有空间: SELECT regexp_replace('
我正在设法创建我的第一个复杂的 J2E 解决方案,并且在每个教程中我都发现了某种中间表的用法,如下所示: 表:用户、用户角色、角色虽然逻辑会简单地向用户表添加一个键来引用它在角色表上的角色,但为什么要
我正在寻找以下解决方案。我想定位一个图像元素,例如 在中间。所以高度是视口(viewport)的高度,宽度会自动设置,图像的中间应该在视口(viewport)宽度的中间。 我搜索的一个例子就像下面的网
我正在设计一种布局,它更像是注册用户的个人仪表板。我让它变得简单,使用基本的 2 列网格,一个用于侧边栏,一个用于主要内容。 因为,例如,80% 的网站使用将发生在一个单独的子系统中,在无 chrom
我有三个不同的 div 标签(不在彼此内部)和代码,所以它有一个把单词放在左边、中间或右边,但中心非常偏离中心。这是 HTML 代码: .desc { float: right; color:
我有以下CSS http://jsbin.com/azivip/75/edit我想让黄色的 div 高度填充蓝色和绿色 div 之间的空间。使用高度继承似乎使 div 超出了绿色 div。 有什么想法
我不得不在其父元素的中间放置一些文本。我用下面的代码实现了它: #div1 { position: relative; margin: 0; padding: 0; } #div2 {
发现一个使用合法证书(由thawte 签名)的网站,但所有浏览器都会拒绝它。我不明白为什么。thawte 的支持告诉我一个域有两个证书,然后将这个 https://www.sslshopper[dot
我正在尝试使用 OpenSSL 创建证书链,但出于某种原因,当我在我的计算机上安装我的根 CA 并尝试验证证书链时,它总是告诉我它找不到证书的颁发者.为了让事情发生,我必须安装中间 CA,这是没有意义
我看到 REST 的一大好处是依赖 HTTP 缓存。我不是在争论这个,而是完全认同这个想法。但是,我从来没有看到对中间 HTTP 缓存的更深入的解释。 如果我将 Cache-control heade
查看此图片 Facebook Messenger Android App Buttons ( MESSENGER\ACTIVE ) 我怎样才能做到这一点? 详细信息:- 带有 2px 红色边框的 di
我的任务是制作漂亮的文本,在文本中间加一条白线,如下图所示。是否可以使用 css 来实现?这是 Fiddle .container{ height:200px; width:400px;
在拉丁文字中,字母有大写和小写形式。在 Python 中,如果你想比较两个字符串而不考虑它们的大小写,你可以使用 'string'.upper() 或 'string'.lower() 将它们转换为相
我正在使用 awk 对文件进行一些文本处理。例如删除尾随空格。 awk '{gsub(/ +$/, "")} {print $0}' filename 这很好用。但是当我将输出重定向到原始文件时。它变
我是一名优秀的程序员,十分优秀!