Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 试图理解旅程::路径::模式#规范(轨道路由的内部)_Ruby On Rails_Routes_Internals_Journey - Fatal编程技术网

Ruby on rails 试图理解旅程::路径::模式#规范(轨道路由的内部)

Ruby on rails 试图理解旅程::路径::模式#规范(轨道路由的内部),ruby-on-rails,routes,internals,journey,Ruby On Rails,Routes,Internals,Journey,上下文:我正在解决一个需要外部审计程序才能理解和“应用”Rails路由的问题。编写此外部程序的一个选项是解析rake路由的输出,但这将不必要地导致复制解析这些路由并将其转换为结构良好的travel::Route对象的代码 因此,我的计划是将Rails.application.routes输出为一种公共格式(YAML或JSON),外部程序可以理解该格式,并可以基于该数据构建路由器 问题:鉴于此上下文,我试图理解旅程::路径::Paternet#spec属性的结构,该属性出现在旅程::路线对象中,恰

上下文:我正在解决一个需要外部审计程序才能理解和“应用”Rails路由的问题。编写此外部程序的一个选项是解析
rake路由的输出
,但这将不必要地导致复制解析这些路由并将其转换为结构良好的
travel::Route
对象的代码

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

问题:鉴于此上下文,我试图理解
旅程::路径::Paternet#spec
属性的结构,该属性出现在
旅程::路线
对象中,恰好是所有操作的中心

例如,以下路由-
/posts/:id
-转换为以下“spec”——

#
  • 旅程::节点::Cat
    对象中的左/右属性是什么?什么决定了哪个令牌是“左”令牌和哪个令牌是“右”
  • 这看起来很像二叉树,但为什么第一个标记(即第一个
    /
    )是“最里面的”(或叶节点)?它不应该是“最外层”(或根节点)吗
  • 在执行路由匹配时,沿着此数据结构走下去的有效方法是什么

旅程基于匹配路线的有限状态机,有内置的可视化工具(需要graphviz):

travel::Nodes::Cat
只是您可能遇到的节点类型之一,它是匹配路径中
表达式
规则的二进制节点,左侧是第一个
表达式
右侧
是所有其他节点,这将生成使用所有表达式的循环

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

  • 具有非纯函数的动态约束(例如-
    get:r,约束:->{rand(2)>0}
    ,其思想是结果可以依赖于请求、时间或状态等之外的内容)当这些存在时,即使rails路由器本身也可以在对同一请求进行第二次运行时产生不同的结果

  • 安装的机架应用程序-可以具有硬编码或非rails路由器

  • rails引擎——有rails路由器,比一般的机架式应用程序更容易,但有安装点和合并到主应用程序范围的技巧
但对于简单的情况,您可以点击rails的
ActionDispatch::Routing::RouteInspector
,它用于
rake routes
,并获得结构化路由信息,这比只解析后一个输出更好

在gem
routes\u coverage
中,我这样做:

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
类检查器
旅程基于匹配路线的有限状态机,有内置的可视化工具(需要graphviz):

travel::Nodes::Cat
只是您可能遇到的节点类型之一,它是匹配路径中
表达式
规则的二进制节点,左侧是第一个
表达式
右侧
是所有其他节点,这将生成使用所有表达式的循环

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

  • 具有非纯函数的动态约束(例如-
    get:r,约束:->{rand(2)>0}
    ,其思想是结果可以依赖于请求、时间或状态等之外的内容)当这些存在时,即使rails路由器本身也可以在对同一请求进行第二次运行时产生不同的结果

  • 安装的机架应用程序-可以具有硬编码或非rails路由器

  • rails引擎——有rails路由器,比一般的机架式应用程序更容易,但有安装点和合并到主应用程序范围的技巧
但对于简单的情况,您可以点击rails的
ActionDispatch::Routing::RouteInspector
,它用于
rake routes
,并获得结构化路由信息,这比只解析后一个输出更好

在gem
routes\u coverage
中,我这样做:

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
类检查器
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