最近阅读Rebuilding Rails时对自建ruby web framework
有了兴趣, 就模仿 rails 的功能写了个.
目的不是再造个轮子, 我也没有这个能力, 主要是想在自己写框架的过程中理解 rails 的基本工作原理, 提升一下自己的水平. 这只是一个演示项目, 没有半点的实际使用价值, 唯一的作用就是便于阅读, 在阅读的过程中可以了解一些 RAILS 的基本原理.
项目地址: https://github.com/suffering/learnmvc
贴上部分 README:
这个项目的目的不是重写一个Ruby web framework
, 而是在自己开发一个Rails-like framework
时, 试着去理解一个ruby mvc style web framework
的一些基本原理.
Rails
的源码就是头恐怖的怪兽, 无数的童鞋倒前仆后继地打开源码, 而后倒下.
Rails
看起来就像魔法, 运行rails s
, 而后一切就开始运行了. 这些行为都是从哪里开始的? 客户端的请求到达后它如何接收?如何处理? 为什么在 controller 里可以调用 Model 里定义的模型? 为什么 controller 里的实例变量可以在 view 中运用? Rails 是如何将 erb 文件渲染而后生成内容的? 它如何与 layout 协作并返回?如此种种.
对于新手来说, 这个就是魔法, 虽然很疑惑, 却是没有时间也没有能力去寻找这些答案. 同时, 新手也不需要去理解这些因为哪怕不理解, 只要懂得 rails 的规则, 把相应的东西写在相应的地方 (MVC), rails 就会将它们组合在一起, 生成内容并打包发送.事实上, 很多人即使不了解这些, 只要对 rails 足够了解, 经验充足, 也可以写出很好的项目来.
但是这样是不够的, 只有更多地理解 rails 的内部原理, 才能更好地使用它, 写出灵活高效的代码.
match
, resources
, get
, post
, put
, delete
等方法自定义路由. 如 match '/products/:id' => 'products#show'
.activerecord
作为ROM
注: 已实现的只是 rails 的九牛一毛. 展示的只是基本的调用链. 及 MVC 基本的结合方式. 许多功能诸如 session, cache, secure, test, configable 等都没有实现.
match
, get
, post
等方法时, 生成路由规则加入路由表. 路由表里包含路径字符串的匹配正则, controller, action, params 等等.env['PATH\_INFO']
, 若匹配, 就知道了指向哪个 controller 的哪个 action, 以及其 params. 通过 ctrl_const = Object.const_get(params[:controller].capitalize)
来得到相应的 controller.controller#action
的基本过程. 也即处理 request 的过程完成.Tilt
gem, 按规则生成目标 view 的名字, 找到它, 而后 render, render 时将 self 作为 scope 传入. 至此 view 里可以调用 action 里所有的实例变量.Tilt.new(view).render self
得到了应该返回的 html 的内容.Tilt
, 将上一步得到的 partial view 放到 block 中提交过去. 这样 layout 中的<%= yield %>
关键字生效. 至此, 得到完整的 html 内容.git clone https://github.com/suffering/learnmvc.git
cd learnmvc
#在编辑器中打开
cd srbmvc
bundle install
cd ../simpleapp
bundle install
rackup -p 3002
#通过rackup方式打开后, 代码在更改后不会自动重载, 可以考虑使用rerun
# gem install rerun
# rerun 'rackup -p 3002'
#以这种方式运行, 对任何文件的修改都会重载代码. 简单模拟rails的development mode.
Demo app 运行后, 可以看到项目正常运行.
查看simpleapp
的源码, 你会看到它的基本结构与 rails app 基本相同.
查阅srbmvc
的源码, 按前文的基本逻辑栏来查看代码, 观看其调用链. 代码中有少量的注释,没有解释具体的细节, 只简单标注出此方法实现的目的与功能. 此部分代码的关键点在于从 request 开始后的调用链, route 规则的指定与检查, controller#action 的定位 以及 render view 部分. 其他皆渣.
请将simpleapp
与srbmvc
结合来阅读.
最好的学习方式是, 看完后, 自己写一个. 在写的过程中, 会发现很多以前注意不到的细节. 在实现 rails 的各种功能的过程中, 你必须对 mvc 的协作方式进行深入思考. 人在思考的过程中成长.
感谢@wikimo同学帮忙纠正错误~