是这样: 前段时间读了《Learn Web Development with Rails》(Michael Hartl)这本书。跟着书从头到尾自己动手做了一遍。因为我是首次接触 Web 开发,虽然可以写,但是不是很明白。现在呢,想写写小应用练习,但是不知道从哪里开始了。主要是一些顺序,像 Modules,Controller,View,Rout 这些以怎样的顺序开始写。在网上查了很多,没找到一个好的。要么太笼统,或者不全之类的。 现在假设一下,其他的事已经弄好了,开始写代码了: $ rails new app 这之后的都有哪些步骤,顺序又是怎样的? 还有思路是怎样的?
不知道有没有表达清楚,大概意思就是,不能太笼统,又不能太详细。点到即可,省下的可以自己去搜索。
BTY,有没有简单的开源网站源代码可供新手学习?(感觉 Ruby China 还是有点复杂)
RailsCasts China 的代码更适合阅读学习。 https://github.com/pragmaticly/railscasts-china
@yedingding 下了最新的 railscasts-china 代码看了,虽然用了 upstream 的 rails repo,但完全没用到 rails 4 的重点介绍的新特性。看来我错了,谢谢提醒。所以你提到的* railscasts-china 的代码确实相比 ruby-china 更适合阅读学习 *是正确的,我错了。;-)
我之前下过 railscasts-china 的版本,在 Gemfile 上遇到很多坑,所以我想当然的认为,既然是 upstream 的代码,稳定性很难保证,如果是新手如果一次配置不成功,挫败感很难抹去。但这一次新 fork 的代码没出问题。
下图是我跑的环境截图,我仍然担心有多少新手会读懂 spec 代码,并且梳理出开发流程思路。anyway,还请@yedingding 能有机会讲讲 rspec,让我也开开眼界。这方面我还是需要加强。
#8 楼 @xds2000 用 upstream 只是为了等 Rails 4 出来的时候不用去做 upgrade,会尽可能避免一些只能在 Rails 4 里有的东西。估计 @poshboytl 会在 Ruby China Conf 上讲这些测试方面的东西,大家一起期待吧,:)
我也是新手一枚,可能比楼主接触的早一些,多一些,且谈谈我的一点体会吧。
事实上,我觉得楼主你现在面临的问题并不是具体的技术细节,因为常规的功能在过了一遍 Rails Tutorial 之后应该就都学会了,无非就是自己动手的时候想不起来。不过这也简单,多看看范例和 API 就好。
对于初学者而言,最麻烦的就是不知道该如何下手,这个楼主也提到了。我觉得原因不在于具体的技术,而在于对整个产品开发过程的了解还不够。换言之就是对全局的把握和掌控,我想这个需要长时间和大范围的涉猎积累才能有所进步。大多数的 coder 都会写具体的功能,但是却不会从宏观的角度规划一个产品的 roadmap,在常规的开发团队里,这通常都是项目经理或是产品经理的工作,而工程师只需要看着需求文档一个功能一个功能,一个模块一个模块的实现下去就好了,因此就不会觉得迷茫。
问题就是,对于绝大多数个人开发者,并没有参与全局开发的经验,更不要说全局性的设计一个产品了,所以具体的某个技术好学,但总是缺一条线把这些技术连接起来。所以呢,我的建议是在领略过 Rails 的概貌之后(比如说过了一遍 Rails Tutorial),先去了解一下一个完整的 web 产品的组成,梳理出一个线路图出来,就容易找到方向了。
这个事情并不是想象中那么复杂,我们完全可以参照一些成熟的产品架构来学习。举个例子吧,比如说你要开发一个论坛类的产品,那么你首先要为这个产品定义一下大体的功能。我们不谈那些独创的特色功能,就从复制一个典型的论坛说起,都需要什么呢?(这个要靠你自己想,如果你想不出来,就多去看看别的论坛,分析它们拥有哪些功能,功能之间是如何交互和组织的等等。)
这个时候,你要学会自言自语,对着自己说:“假设当我第一次访问这个论坛的时候,我首先看到的是一个欢迎页面。这个页面是否会有动态的内容暂时我还不确定(比如说从论坛的所有板块里提取出的热点话题等等),所以我先当它是个几乎静态的吧。”
此时,你会面临一个选择:我是要生成什么?scaffold? model? controller?
Rails Tutorial 里实际上给出了答案,就是在最开始解释 MVC 模型的时候。
对于一次不需要和数据库交互的用户请求,MVC 的处理过程是:用户请求(浏览器:发出请求)-> 路由(router:将请求映射至控制器的行为,也就是 action)-> 控制器(controller:对应的 action 处理相应的请求,处理后交给视图渲染)-> 视图(view:渲染完成交还给控制器)-> 控制器(controller:将结果返回给浏览器)-> 输出(浏览器接到发出请求后的响应)
可以看到,这个过程里没有 model 的参与,这是因为我们假设的目标是一个静态的页面,是不需要和数据库模型交互的。这个过程实际上就是 Rails Tutorial 里前五章的内容。
于是,答案就是生成一个 controller 就够了。scaffold 生成的是一个完整的 RESTful 资源,包括了 model, controller, views, assets, test...显然超出了我们的预定计划(当然它也可以做到我们要做的,只不过有点资源浪费罢了),目前需要的不是一个完整的 resource。
此外,你还可以多想一步(可选,即使现在想不到,将来也可以手动添加):既然上述的流程说的是来自用户的一次请求,那么对于其他的请求呢?
刚才提到了,router 负责将用户请求映射至 action(在 controller 中),那么对于静态页面来讲,基本上就是你有多少个页面,就要有多少个 action,因为每一个页面都会用一个独立的 URL 来确定位置,也就是有一个独立的请求。
所以,假设我们的静态页面有:首页、关于、帮助、联系,于是我们就可以开始动手执行:
rails g controller static_pages home about help contact
在这条命令里,static_pages 就是控制器的名字,意思是“静态页面”(这个不是强制的,我只是模仿 rails tutorial 里的做法,这样 LZ 你也比较熟悉。实际开发中我喜欢对静态页面控制器命名为 portals 或者 entrance,请随意),也就是“用来控制静态页面部分的控制器”。在这个控制器中,拥有四个 actions:home / about / help / contact,分别对应计划中的四个页面(当然可以用别的名字,只不过 routes.rb 里的配置要和它们一一对应,另外不要用 CRUD 的名称,因为它们是和 RESTful 资源对应的——这就是“惯例重于配置”的思想)
接下来,router 里面设置好如何将用户请求转至对应的 action:
root to: "static_pages#home"
get '/about', to: "static_pages#about"
match '/help', to: "static_pages#help", via: 'get'
match '/contact', to: "static_pages#contact"
这几句用语言表述下来就是:
对于来自网站的根路径(root)的 get 请求,如:http://myapp.com/
,转交给 static_pages 控制器的 home 行为(action)来处理
对于来自网站的 about 路径的 get 请求,如:http://myapp.com/about
,转交给 static_pages 控制器的 about 行为(action)来处理
以下雷同,第三个 match + via: ‘get’等同于第二个直接 get;第四个只有 match,代表对于来自该路径的所有类型的请求(get post put 等等);这里都是举例,实际情况实际处理。
OK,到了这一步,控制器已经可以通过 action 将处理的结果交给 views 渲染了。对于静态页面来讲,action 的内部几乎不需要写代码,rails 通过 action 的名字就可以找到对应的 views。比如说对于 about action,对应的视图就是/app/views/static_pages/about.html.erb
接下来,你在视图里写什么,浏览器就可以通过 http://myapp.com/about
看到什么。
再往后,搞定静态页面之后,你大概会先碰到注册、登陆、验证三部曲。那么这就需要用到 model 了,因为你需要在数据库里记录一个注册用户的信息啊,对不对?那么实现的思路其实和上面也没什么不同,无非就是在 MVC 的工作流程里多了 model 这个环节,同时 controller 要负责的逻辑处理也酌情增加,于是整体的复杂度有所提升罢了。
That's it! 总结一下就是:
即兴写就,看着有点乱,还请各位海涵,希望对 LZ 有用。
没有特殊的顺序,这个需要实践,需要结合不同的项目,不同的场景,不要拘泥于这些形式。 http, html, css, javascript, ruby, rails 组件,mysql,数据库。
#14 楼 @alijan 首先,不用客气,大家都是一路摸索,有些心得体会相互交流也是应该的。
关于你说的第六点,这个恐怕就是“大概”说一下也能写出一本书来,呵呵,我自认还没那个能力,也还在学习摸索之中。所有的知识,目前我获得的,无非就是通过几个途径:搜索、教材(书、互动教材)、视频、读源码。诚然如你所说,一时得来的结果未必适合新手看,但需知从新手到高手都必须要有个过程,在这个过程里没有捷径可走。
如果我们请一个高手“大略”说说这些复杂,那么即使他说完了,新手看不懂的地方还是看不懂;除非他更加深入浅出的说——那就真的是长篇大论了,会涉及到 N 多书籍、教程、视频、搜索的结果。那么这样就真的好吗?我觉得不是的。因为每一个人的基础起点不一样,对事物理解的方法和顺序也不一样,直接喂到嘴里的饭未必会觉得好吃。
一时看不懂是没有关系的,记下来(不是死记硬背,而是留心知识点之间的关联)先,慢慢去理解。另外,在这个过程中,保持旺盛的好奇心是至关重要的。
拿我自己来说吧。最开始我被 Rails 所吸引是因为神奇的 ActiveRecord,有人告诉我说你用 Rails 去写 web app,可以完全不用考虑 SQL。这句话真的 hit 我了,因为作为一个编程菜鸟,曾几何时我也特别渴望自己写一个 web app,但是艰涩的 SQL 总是让我望而却步(当然,也是因为懒,下不了那个决心去学会它 ^^)。在没有类似 ActiveRecord 的年代,应用程序每一次要从数据库里获取数据都要写又臭又长的 SQL,而且获取数据的逻辑越复杂、条件越繁多,SQL 语句的复杂性也就随之增加;更要命的是,完成同样的数据库请求,SQL 可能会有多种写法,它们之前会存在效率不同的问题,如果你不熟 SQL,你真的很难很好驾驭它。
我真的是因为这个原因才开始接触 Rails 和 Ruby 的,不久就被它们折服了~~~Rails 做了什么?ActiveRecord 所做的一件重要的事情,就是把一系列复杂的 SQL 查询封装起来,留给我们一些简单、容易理解、可以灵活组合搭配的接口供我们调用。于是,你真的可以完全不考虑 SQL 的问题,并且它还保留了让开发者继续写原生 SQL 语句的自由,这样你即使不信任 Rails 封装的一系列方法,也依然可以按照自己的方式来。
Rails 开发组以及社区的活跃份子们通过大量的努力积累了一系列的最佳实践,并把它们扩充进 Rails 丰富的 API 之中,使得 Rails 日益完善,能够应对现实开发需求中各种各样对于数据查询的要求。它是简单,但是简单背后也有复杂的一面。我在开始学习的时候总觉得有些数据查询似乎用 ActiveRecord 也是满足不了的,然而无一例外的在过一段时间之后我就会在书里、视频里、或者搜索的时候发现:哦,原来 Rails 是可以的,只是我还不知道!所以,你需要什么?你需要不停地探索、挖掘、积累。
更有意思的是,因为学习 Rails 让我充满了好奇,我慢慢地也学会了很多 SQL 了。这是因为有的时候当我觉得 Rails 神奇的我无法理解的时候,我就会去看源代码,试着理解它背后的实现。当然,有的时候可以成功理解,有的时候嘛,道行还是不够啦。Anyway,至少每一次探险都能让我学到一些东西,于是日久天长,SQL 我也能熟门熟路了。所以当我看到或听到有些人说:“不要去学 Rails,它就像傻瓜照相机,虽然简单,但却会让你学不到真东西”的时候,我个人是不以为然的,因为能不能学到真东西完全取决于你怎么学,而不在于“老师”怎么教——当然,像 Rails 这么优秀的“老师”还是值得尊敬的,因为它凝聚了 Ruby 的优雅和众多开发者的集体智慧。
就象这样,Rails 表象的简单和它背后隐藏的复杂相辅相成,简单是为了好用,快速应对现实开发的种种需求变化,但开发者应当以这种简单为起点而不是终点,否则就会变成“知其然不知其所以然”,当然就不会创造出伟大的产品啦!
这是一个关于 ActiveRecord,也就是 Model 部分的例子。还有一个让我体会很深的是关于 RESTful,我想所有的初学者在读入门教材的时候都会看到作者有介绍 RESTful,并且都会推荐进阶阅读,那么大家是否真的去看了呢?你对 RESTful 了解有多少?CRUD 为什么会成为“惯例”?HTTP Methods 究竟如何发挥作用?这些问题你好奇过吗?探索过吗?
以前我就没有,因为“面向资源的架构”神马的,这样的词我一看就头大,我一直觉得这是架构师级别的大侠们研究的领域,我不觉得像我这样木有计算机专业背景,只当了不到一年的前端页面工程师能够驾驭这种重量级的话题。但是 Rails 再次改变了这一切,当我学了一段时间 Rails 觉得有点恶心,停滞不前的时候,我遵循了那些教材里的建议,去读了几本书,其中《RESTful Web Services》这本真的是让我有醍醐灌顶的感觉。可以这么说,在 10 楼的回复里,讲解范例的那一段,若不是因为我读了这本书,我想我是不可能解释到这个程度的。而上述的一切,若非是 Rails 领我进门,我想我也是不可能会去学习和理解的。
总得来说,我个人觉得 Rails 是很适合初学者——特别是没有什么计算机背景和开发经验的初学者——学习的 Web 开发框架。我这么说并不是因为它很简单,可以让你 3 个月速成写出一个 Github 来:这是不怎么现实的;我这么认为,是因为以下几个原因:
Rails 是用 Ruby 开发的。Ruby 是一门非常非常适合入门的语言,并且它也是一门非常非常强大的能用一辈子的好语言。它的好在我看来最重要的一点就是优美的表达能力!特别是对于像我这样只有 HTML+CSS 经验的初学者来讲,这一点非常重要,学习 Ruby 第一次让我有了我不只是在写代码,我更是在表达和交流的感觉(我是文科生,接近于自然语言的表达方式更能让我产生共鸣和理解)。在此之前,我曾试图学习 Java / C++ / PHP,PHP 算是最简单的了,但我学得都痛苦无比,唯独 Ruby 让我倍感亲切和自然。
正如 Aaron Patterson 在 RailsConf 2011 发表的演讲中所说,Rails 是一个开发框架,但它不只是一个开发框架,它以及社区选择和它一起工作的所有工具共同组成了一个美妙的 eco-system(生态系统)。如果不是因为 Rails,我不可能会去学 CLi;如果不是因为 Rails,我不可能会去学 Git;如果不是因为 Rails,我不可能会去学 TDD……你可以说学 Rails 是一个大坑,我要说那得看你的追求如何,因为无论你是否选择 Rails 或是 Ruby,只要你想要做出优秀,甚至是卓越的应用程序,这些坑你是必须要填满的,sooner, or later.而 Rails,这是引导并伴随我们走过这一路的最佳伙伴——也许不是唯一,但至少很适合我——每当你迷茫不知前路何处的时候,去看看那些 coder 用 Rails(或者 Ruby)做了什么,你总能学到些什么。
我无法告诉你未来,或许几年以后 Rails 都不是我的第一选择了,因为我也时常听到看到别人说它的缺陷:并发处理、可扩展性、安全性、性能瓶颈……等等等等,我还没到这个地步,我往往都听不懂他们在说什么?不过这不是问题,朝好的方向想想,我对自己说:若不是来学习 Rails,你甚至都不会有机会去了解这些!总有一天,当你了解了复杂事物的方方面面,相信你一定会做出最佳的判断和选择。
Keep moving on...with Ruby & Rails.
想到什么写什么,需要什么用什么,看到脸熟的代码就要想要不要重构。找个自己身边需要用的小 app,从 0 开始,一个 model,一个 action,一个 controller,循序渐进,终成大牛。
@nightire 你已然成为了我心中 Rails 的导师。文笔思路都给我这等菜鸟新手有了很大的帮助。
“如果我们请一个高手“大略”说说这些复杂,那么即使他说完了,新手看不懂的地方还是看不懂;除非他更加深入浅出的说——那就真的是长篇大论了,会涉及到 N 多书籍、教程、视频、搜索的结果。那么这样就真的好吗?我觉得不是的。因为每一个人的基础起点不一样,对事物理解的方法和顺序也不一样,直接喂到嘴里的饭未必会觉得好吃。”
这句话的确是个道理。但是在我学习的道路上一直有个坎,我不习惯去学习一个我一开始就全然不懂不知何物却又硬生生摆在那里的东西,然后背着这个巨大的心里疙瘩痛苦的看完一大段之后才恍然大悟。能恍然大悟固然好。可是,那段背负着疙瘩的路实在是走得难受。(如果那时有人能稍微提醒你两句,哥们,那个不重要,先放过去吧。的确会好很多的。)
在学习 Rails 路上经常会遇到一些个小疙瘩,其实后来想来,也会觉得那些只是个很细小的东西,可是当时在看的时候心里却老是放不过去。总想着把路上的每个细节步骤都弄懂,不说明了,至少知道是为何物。如果重要则新建知识分支,细看;不重要,心里也可以舒坦的继续下去了。。。
#21 楼 @346617552 你谈到的这个问题在我个人看来是这样的:我从来不认为哪一个“疙瘩”是不重要的,仅仅是优先级有区别。一个“疙瘩”就是一个坑,如同我上文所说:如果你的志向就是这一行,就是要开发出卓越的产品,那么这些坑你迟早都是要填满的,因此在我看来所有的“疙瘩”都很重要。
只不过学海无涯而吾生有涯,或许我们没有那么多时间去填满所有的坑,更加明智的做法是排出个顺序来,一步一步的吃掉它们。
首先,大前提是我必须要清楚我的总体目标是什么。其次,在前进的道路上如果遇到了“疙瘩”,我会给自己一个时限去了解一下它是什么?它有多重要?它有多复杂?掌握它需要花费多少代价?通常我会给自己半小时时间去搜集这些信息。
这里我有一个个人的小技巧:我对面的墙上贴着一张大大的白纸,白纸的中心是我的目标,然后向四周延伸出去,每一条延伸线都代表了达成这个目标所必须要完成的路线,比如说:设计、前端、后端、部署、文档、商业模式……等等;之后每一条路线上都会有各种各样的分叉、再分叉、再再分叉……它们分别代表一个坑,或者说一个“疙瘩”。我花半个小时去了解一个坑,然后确定它属于哪一条分叉,并且写出它在我心中的优先级,这个优先级取决于几个因素:它对整体路线的影响力;学习它的难度和时间消耗程度;它是必须我独立掌握的,还是可以交由团队其他成员掌握即可等等。
然后,就放下它吧,继续你之前的进度,反正它已经在你的“黑名单”上了,逃不了的。更重要的是,我不能让它成为我的心结,不能老惦记着却不做任何事情。
一开始肯定会比较头大,因为“黑名单”太长了……不过请不要担心,一个人建立知识体系是漫长的过程,但是体系的节点之间总是有着千丝万缕的联系,经过一段时间有规划的学习之后,你就会发现实际花费的时间和精力总是少于你的事前估计的。
要相信自己,也要养成习惯,更重要的是:不要去想未来还有多长,专注于眼下吧,因为担心未来的功夫浪费的正是眼下的时间。
@nightire 大师,麻烦能写一篇文章给我们讲解一下“测试”吗?看过 Rails Tutorial,里面关于测试的代码实在看不下去。。。什么“断言”。。。每次都是直接 copy+paste......非常想听听你对“测试”讲解啊。。。。。。TDD BDD 什么的。。。对于新手学习开发哪种更好些?
#25 楼 @346617552 呃,拜托~不要叫大师,我差几万条街去了……关于测试,其实我最近也才开始系统的学习,主要是看 The RSpec Book 这本书。所以说我还达不到讲解的水平,因为我自己还没完全理顺,我就讲几点目前我感受比较深的吧。
一开始我和大多数初学者一样,认为“测试”是一种质量保证工序,毕竟字面意义上来看的确是这个意思。但随着了解增多我慢慢领悟到一件事情:测试驱动开发(Test Driven Development)这个概念当中,最重要的不是“测试”,当然也不是“开发”,而是“驱动”。
这句话怎么理解呢?“开发”是目的,“测试”是手段,“驱动”则是连接二者的桥梁,我们在测试过程当中使用的每一个技巧,每一行代码都是为了达到“开发”的目的。
假设你要为自己的项目开发一个功能,我们可以将这件事情分解成三个阶段:
Context
字面意义上:Context 指的是上下文或者说情景,在这里是指目前你所处的状况。通俗地讲:你要开发一个功能,是因为你遇到了某个问题或需求,你要解决或满足它,这是前置条件。你应该注意到写测试的时候总是要“描述”(describe)这些“情景”(context),对吧?
Procedure
第二个阶段就是实现它的过程啦,这里我先跳过,后面反过来会讲到。
Result
最后我们获得了结果,这是毋庸置疑的。
如果没有测试驱动开发,上述三个阶段会顺序走下来(1-2-3),但是阶段 3 的结果是不可控的,有可能成功,也有可能失败,还有可能表面上成功了但实际上没能满足一些极端情况(通常称作“边缘案例”,edge case),又或者隐藏了一些难以发现和排查 Bug,再或者实现不够简洁导致性能底下……等等。
简而言之,就是不但阶段 2 会走的比较辛苦(要解决的问题越困难越复杂,就越辛苦),阶段 3 的成果还未必很令人满意。
那么测试驱动开发能帮我们做了什么?
我的看法是这样的:使用“测试驱动开发”的理念和方法来进行开发,最关键的一点就是把解决问题的思路和习惯逆转过来,采用倒推法。
当你处于阶段 1 的时候,阶段 2 对你来说是未知的,你完全无法预见这个过程会经过哪些考验,你的代码会变成什么样子,但是阶段 3 却是你可以预见的。也就是说,当你面对一个陌生的问题需要去解决的时候,你无法预见你会如何去解决,但是你可以预见到一旦解决后的结果如何。
所以,你先写结果,也就是你提到的“断言”。你可以对自己说:我推断,一旦我实现了这个解决方案,那么我可以获得这样的结果。
神奇之处就在于,测试驱动开发的框架真的可以帮你验证这个结果,并且告诉你“距离你期望的这个结果还有多少路要走”。
我们来举一个非常简单的例子。假设你要做一个功能,根据给出的条件显示不一样的信息:(以下都是伪代码):
你所处的“情景”是:当我给条件 A,显示 C;给出 B,显示 D,所以:
describe Dosomthing do
context "given condition A" do
end
context "given condition B" do
end
end
接下来,执行代码并传入不同条件(注意此时DoSomething
根本就是空的,什么都没做)
describe DoSomthing do
context "given condition A" do // 实例化,传入条件B
result = DoSomething.new(A)
end
context "given condition B" do // 实例化,传入条件B
result = DoSomething.new(B)
end
end
此时,测试驱动框架所做的事情就是帮你执行你要的代码,然后获取执行的结果。在这里有一个问题值得初学者留心:它是去哪里执行的呢?它怎么知道这里执行的DoSomething.new
就是我们想要做的的那个DoSomething
?
如果你做的是一个 Rails 程序,那么答案就在环境变量里,你还记得 Rails Tutorial 里有一个spec_helper.rb
文件吗?你还记得每次写一个测试文件都要在开始处声明request 'spec_helper'
吗?没错,它的作用就是帮你载入应用程序里的文件(准确说,是载入 test environment),如果测试框架能找到DoSomething
,它就执行。
如果是 Ruby 程序或者其他的什么情况,那么你可能需要手动请求你的实际代码所处的文件,就象这样:require 'lib/do_something.rb'
,如果不做这件事情,那么测试框架也搞不懂你到底要测试什么的。
好,现在测试框架知道你要测试的目标和执行的方法了(其实在背后,它也能够获得执行你的代码的结果了),最后一步就是告诉测试框架,你期望的结果是什么?也就是你的“断言”:
describe DoSomthing do
context "given condition A" do
result = DoSomething.new(A)
result.should equal_to(C) // 这个实例返回的结果应该等于C
end
context "given condition B" do
result = DoSomething.new(B)
result.should equal_to(D) // 这个实例返回的结果应该等于D
end
end
当你运行测试,它可能会告诉你:找不到DoSomething
(或者是result is nil
?反正一个意思吧,记不清了,呵呵)
OK,我忘了定义我的类和构造器了,要么就是我们把文件加载进来;
然后它就说:“我期望看到 C,但是现在是空”之类的,那么你就要去满足它,让它看到 C!Just do whatever you can.
你当然不能指望测试框架告诉你:你应该“if A then C, elsif B then D...”——这不可能,它还没聪明到这个地步——如果真这样了还要开发者做什么?还要开发程序做什么?
不过,虽然它们没那么聪明,但至少从上面的例子里我们可以看到几个很明显的优点:
我艹……不知不觉又扯这么长,不带这样的啊,这些东西多看看书应该很容易理解的嘛……虽然测试还有很多好处和技巧,比如……我会告诉你我都知道吗?睡觉吧,哥~
@nightire 呵呵,看完啦~~~ 小有收获啊~~~我就觉得所有的 Guides 都应该你这么写,那才叫 Guides 嘛,要不就只能叫 Reference。会多自己看的,不过至少现在已经知道将要看的可以带来什么知识点。心里有底感觉好些。 估计你回答多几个就可以作为《Rails 新手引导》了。。。谢谢了,哥~