首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >试图理解Journey::Path::Pattern#spec ( Rails内部路由)

试图理解Journey::Path::Pattern#spec ( Rails内部路由)
EN

Stack Overflow用户
提问于 2019-04-03 04:50:22
回答 1查看 227关注 0票数 0

上下文:--我正在解决一个问题,需要一个外部审计程序来理解和“应用”Rails路由。编写这个外部程序的一个选择可能是解析rake routes的输出,但这将不必要地重复解析这些路由并将它们转换为结构良好的Journey::Route对象的代码。

因此,我的计划是将Rails.application.routes输出到公共格式(YAML,或JSON),外部程序可以理解这种格式,并可以基于这些数据构建路由器。

问题:在这个上下文中,我试图理解属性的结构,该属性发生在Journey::Route对象中,恰好是所有操作的中心。

例如,以下路由- /posts/:id -被转换为以下“规范”-

代码语言:javascript
复制
 #<Journey::Nodes::Cat:0x00007ff193327ee0
 @left=
  #<Journey::Nodes::Cat:0x00007ff193308630
   @left=
    #<Journey::Nodes::Cat:0x00007ff1933087e8
     @left=
      #<Journey::Nodes::Cat:0x00007ff193308bf8
       @left=#<Journey::Nodes::Slash:0x00007ff193308d38 @left="/", @memo=nil>,
       @memo=nil,
       @right=#<Journey::Nodes::Literal:0x00007ff193308c48 @left="posts", @memo=nil>>,
     @memo=nil,
     @right=#<Journey::Nodes::Slash:0x00007ff193308a40 @left="/", @memo=nil>>,
   @memo=nil,
   @right=#<Journey::Nodes::Symbol:0x00007ff1933086d0 @left=":id", @memo=nil, @regexp=/[^\.\/\?]+/>>,
 @memo=nil,
 @right=
  #<Journey::Nodes::Group:0x00007ff193309c10
   @left=
    #<Journey::Nodes::Cat:0x00007ff193308220
     @left=#<Journey::Nodes::Dot:0x00007ff1933084f0 @left=".", @memo=nil>,
     @memo=nil,
     @right=#<Journey::Nodes::Symbol:0x00007ff193308338 @left=":format", @memo=nil, @regexp=/[^\.\/\?]+/>>,
   @memo=nil>>
  • Journey::Nodes::Cat对象中的左/右属性是什么?什么决定哪个标记将“左”,哪个令牌将“右”。
  • 这看起来像一棵二叉树,但是为什么第一个令牌(即第一个/)、“最里面的”(或一个叶节点)?它不应该是“最外面的”(或者根节点)吗?
  • 在执行路由匹配时,有什么有效的方法来遍历这种数据结构?
EN

回答 1

Stack Overflow用户

发布于 2019-04-12 11:13:02

旅行是基于与路由匹配的有限状态机,有内置的可视化工具(需要图形):

代码语言:javascript
复制
File.open('routes.html', 'wt'){|f| f.write Rails.application.routes.router.visualizer }

Journey::Nodes::Cat只是您可以遇到的节点类型之一,它是在路径语法,见parser.y中匹配expressions规则的二进制节点,左边是first expressionright是所有其他节点,这会产生消耗所有表达式的循环。

关于外部路由分析的其他想法:在一般情况下,路由不能转储到静态文件中,因为它们可以包含:

  • 非纯函数的动态约束(例如- get :r, constraints: ->{rand(2)>0},思想是结果可以依赖于请求、时间或状态以外的东西,等等)当出现这些情况时,即使是rails路由器本身也可以在第二次运行同一请求时产生不同的结果。
  • 安装机架应用程序-可以有硬编码或非rails路由器。
  • rails引擎-有rails路由器,比一般的机架应用程序更容易,但是有挂载点和合并到主应用范围的诡计。

但是对于简单的情况,您可以访问rails的ActionDispatch::Routing::RoutesInspector (用于rake routes ),并获得结构化路由信息,这比解析后一个输出更好。

在gem routes_coverage中,我是这样做的:

代码语言:javascript
复制
class Inspector < ActionDispatch::Routing::RoutesInspector
  def collect_all_routes
    res = collect_routes(@routes)
    @engines.each do |engine_name, engine_routes|
      res += engine_routes.map{|er|
        er.merge({ engine_name: engine_name })
      }
    end
    res
  end

  def collect_routes(routes)
    routes.collect do |route|
      ActionDispatch::Routing::RouteWrapper.new(route)
    end.reject do |route|
      route.internal?
    end.collect do |route|
      collect_engine_routes(route)

      { name:   route.name,
        verb:   route.verb,
        path:   route.path,
        reqs:   route.reqs,
        original: route,
      }
    end
  end

res = Inspector.new(Rails.application.routes.routes.routes).collect_all_routes
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55487301

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档