最近阅读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同学帮忙纠正错误~