Rails 路由源码分析
Rails 路由
本文的路由分析是基于 rails 4.0.13
前言
在创建完 rails 应用以后,默认的会生成 config/routes.rb
文件,平时我们所用到的路由入口都可以定义此处,而使用方法也很简单,只需要在块内简单定义一下路由的路径和响应的 Controller 即可,如下所示,可以简单的定义一个 http GET /welcome 的请求,然后到 HomeController 找到名为 welcome 的 action 并执行熟悉的 MVC 过程(ps: 至于代码如何响应并发送,不过这个暂时不在本节讨论范围,本节主要是看看路由是怎么被定义的
1 | Rails.application.routes.draw do |
路由是如何被定义的?
下面开始从第一行代码开始分析,Rails.application.routes.draw
做了什么?
1 | # file: railties-4.0.13/lib/rails/engine.rb |
那么,路由的定义可以简单的理解为
1 | Rails.application.routes.draw do |
我们平时使用的 get
、post
、resources
等等方法都属于这个类 ActionDispatch::Routing::Mapper
的实例方法
下面继续看看 get
方法做了什么事情
1 | module HttpHelpers |
无论是 get、post、put 或是其它,最终的处理逻辑都是跑到 match
方法,而 match 方法的使用方式有很多种,可以看到官方的注释和方法的定义
1 | # match 'path' => 'controller#action' |
add_route
之后又 add_route
,在阅读过程中出现了贼多的 add_route
,感觉就是一层层的套娃。
But,此处就是最最最核心的方法,涉及 route 的存放位置,其实核心代码主要就是两行,咱们可以一行行进行解读, to_route 到底做了什么,这里就不展开说明了,简单来说 to_route 只是把我们的参数进行了处理,使之更加面向对象
app, conditions, requirements, defaults, as, anchor = mapping.to_route
变量名称 | 作用 | 备注 |
---|---|---|
app | Constraints 类实例对象,内部映射着对应的 controller 类 | |
conditions | 上层传过来的 options | |
requirements | 可配置此路由的正则,或者 format;主要用在之后的路由匹配过程,不符合正则或 format 的情况是不会进入到对应路由的响应 | |
default | 用处未知 | |
as | 一般用作路由的别名,eg: get ‘repositories/latest/created’ => ‘project_tags#latest’, as: :latest_created_projects | |
anchor | 用处未知 |
由以上可知,to_route
方法的作用是对用户在 router.rb 定义的 dsl 做一个更细化的处理,处理完成后向 mapper 抛出对应的参数,比如路由的名称,路由的规则,路由的响应,以及其它可配置选项。在此方法的最后,把这些参数都传到 @set
实例变量进行存储起来,而 @set
实例变量在开头 Rails.application.routes
就已经初始化了
1 | # Rails.application.routes.draw 的 Rails.application.routes 就是此方法 |
至此,我们已经解决了第一个问题,路由是怎么被定义以及怎么被存储的:路由在定义之后,在启动应用的过程(rails s),会加载 router.rb 文件,然后初始化类 @set = Journey::Routes.new
,之后将我们定义的诸如get '/welcome' => 'home#welcome'
经过加工处理后,存储到 @set
的 routers 变量
在阅读的途中,我画了一下调用栈来帮助理解
Rails 路由源码分析
install_url
to use ShareThis. Please set it in _config.yml
.