该书下载自书部落分享计算枳经典巨著!一 wwweshubulo com!仅伊 16第2章Rais应用的架构 这种方式简单明了,实际上,很多人正是这样操作关系数据库的。看起来,对于小 型应用,这的确是一个理想的解决方案。然而这里有一个问题:将业务逻辑和数据库访 问搅在一起会使应用程序变得难以维护、难以扩展。而且,要编写这样一个应用程序, 你还得先学会SQL。 譬如说,假设我们英明的州政府颁发了一条新的法令,要求我们记录每笔销售税计算 的日期和时间。这不成问题,你会说,我们只要在循环中获取当前的时间、当 update这 条SQL语句时多加一个字段、将当前时间传递给 execute()方法调用即可。 但是,如果我们在应用程序的很多地方对“销售税”这个字段进行了设值,情况又如 何呢?现在,我们必须找出所有这些“更新销售税”的代码,一一修改它们。我们不得不 编写重复代码,它们会成为错误的源头譬如说,我们可能漏掉其中一处忘了修改。 在通常的程序设计中,面向对象的经验告诉我们:封装可以解决这类问题。我们可 以将与“订单”相关的所有东西都封装在一个类中,这样,当规则发生变化时,只需要 修改一个地方。 人们也将这样的思想延伸到了数据库编程的领域。基本的前提非常简单:我们将 对数据库的访问”包装在一层类的后面,应用程序剩下的部分都通过这些类来访问数 据——它们永远不会直接跟数据库打交道。这样,我们就把所有与数据库结构相关的事 情都封装在一层代码背后,从而使我们的应用程序代码与数据库访问的细节解开耦合。 在这个“改变销售税”的例子中,我们只要修改对“订单”表进行封装的这个类,使其 在销售税发生改变时更新时间戳即可。 不过,实现这一概念的难度比看上去的要大。真实世界里的数据库表是彼此关联的 (譬如说,一份订单可能由多个订单项组成),我们同样希望将这种关联映射到我们的 对象中:代表订单的Oder对象应该包含一组代表订单项的 Lineltem对象。但这样 来,我们就会遇到对象导航、性能,以及数据一致性等方面的问题。和往常一样,只要 碰到这些复杂问题,我们的行业就会为它发明一个三字母缩写词:ORM ( Object-Relational Mapping,对象关系映射)。 Rails就使用了oRM。 对象-关系映射(ORM) Object-Relational Mapping ORM库可以将数据库表映射到类。如果数据库中有一张名为 orders的表,我们的 程序中就会有一个名为 order的类。表中的每条记录对应于该类的一个对象:一条订单 记录将被表现为 Order类的一个对象。在这个对象内部,属性则被用于读/写各个字段: 我们的 Order对象将拥有一些方法,用于读/写“数量”( amount)、“销售税”( sales tax) 等字段的值。 Web开发敏捷之道一应用Rals进行敏捷Web开发,第2版
- 16 i l 这种方式简单明了,实际上,很多人正是这样操作关系数据库的.看起来,对于小 型应用 ,这 是一个理想 案. 然而这里有一 将业 辑和数据库访 问搅在一起会使应 程序变得难 展. 要编写 样一 用程序 你还得先学会 譬如说,假 们英 的州 了一条新 法令 要求 们记录每笔销售 计算 的日期 时间. 这不成 你会说 我们只要在循 取当 、当 pd L语句时多加一个字段、将当前时间传递给 () 方法调用 可. 但是 如果 这个字段进 何呢9现在 们必须 出所有这 更新销售 ,一一修 们. 不得 重复代码,它们会成为错误的源头 一譬如说,我们可能漏掉其中一处忘了修改 通常 诉我 装可 这类 题. 以将与"订单"栩关的所有东西部封装在一个类中 ,这样,当规则发生变化时,只需要 修改一个地方. 人们也将这样的思想延伸到了数据库编程的领域.基本的前提非常简单:我们将 数据库 问" 装在 类的后面 应用 序剩下的 分部通 这些类 访问 据它们永远不会直接跟数据库打交道.这样,残们就把所有与数据库结构相关的事 封装 层代码背后.从而使夜们的应用程序代码与数据库访问的细节解开锅合 这个 例子 只 要修改对 订单 表进行封装 个类 使其 在销售税发生改变时更新时 即可 不过,实现这一概念 难度 的要大. 界里 据库表是彼此关 (譬如说 一份 单可 成) 样希望将 种关 到我 对象 z代表订单的 r对象应该包含 代表 单项 Li m对 .但这样 ,我们就会遇到对 导航、 能, 以及 致性等方 和往 ,只要 些复杂问题 ,我们的行 业就会 为它发明 一个 三字母缩写词 aRM (Object-Relational Mappi ng. • ai 就使 RM 对象·关系映射 RM Object-Relational Mapping 库可 库表 程序中就会有一个名 的类 条记录对应于该类 -个 条订 记录将被表现为 r类的 对象.在这 内部 用于读/写各个字 我们 r对象将拥有一些方法.用于读/写 "数量.. t) .. (sales tax ) 字段的值 Web IiIl ill Rails iHt7lt1# Web !lff2 !t5 该书下载自-书部落-分享计算机经典巨著!--www.shubulo.com!仅供试看^_^
该书下载自-书部落-分享计算机经典巨著!-www.shubulo.com!仅供试看^ 2.2 Active Record: Rails的模型支持 此外, Rails类还对数据库表进行了包装,提供了一组类级别的方法,用于执行表级 别的操作。譬如说,我们可能需要找出具有某一特定ID的订单,这一功能就被实现为 一个类方法,该方法返回对应的 Order对象。在Ruby代码中,这一操作大概会是这 -637 1 样 order Order find (1) puts puts Order #forder, customer id/, amount=#forder. amount 635页 有时这些类级别的方法会返回一组对象的集合: iterating Order. find(: all, conditions =>"name='dave'"). each do Iorder I puts order amount end 最后,每个对象会有一些方法,用于操作自己所对应的那条记录。其中用得最多的 方法大概就是save(),这个方法用于将对象中的数据保存回数据库: Order. find(all, conditions =>"name='dave'"). each do Iorder I order, discount =0.5 order. save end 综上所述,ORM层将数据库表映射到类、将记录映射到对象、将字段映射到对象 的属性。类方法用于执行表级别的操作,实例方法则用于执行针对单条记录的操作。 在一个典型的ORM库中,你可以提供配置数据来指定数据库端与应用程序端之间 的映射关系。使用这些ORM工具的程序员常常会发现:他们不得不忙于创建和维护 大堆的XML配置文件。 Active Record Active Record是 Rails所采用的ORM层。它完全遵循标准的ORM模型:表映射到 类,记录映射到对象,字段映射到对象属性。与其他大部分ORM库的不同之处在于它 的配置方式:它根据人们常用的命名惯例提供了很有意义的默认配置,因此,将需要开 发者编写的配置量降到了最低。为了证明这一点,下面就是一段用 Active record写的、 用于包装 orders表的程序: require 'active record class Order ActiveRecord:: Base end order Order find(1) order discount = 0.5 order. save Meb开发敏捷之道一应用Ral进行敏捷Web开发,第2版
2.2 Active Record : Rails 的模型交指 此外. il 类还对数据 包装 组类 别的 执行表 别的操作.譬如说,我们可能需要找出具有某-特定 ID的订单 ,这一功能就被实现为 一个 方法 该方 对应 对象 一操 会是 样: e r = Order .find(ll puts ·Order #{order.customer_id} , amount=#{order.amountj- 有时这些类级别的方法会返回一组对象的集合 Order.find(:all. :conditions => -name='dave' -) .each do lorderl puts order.amount end ,每个对象会有一些方法,用于操作自己所对应的那条 .其中用得是多的 大概就是 () 这个方法 于将对象 数据保存回数钳库 Order.find( :all, : c ondi t i ons => -name= 'dave' ·j . e a c h do lorderl rde r cou = 0 .5 e r save end 上所 4层将数据库表映 类、 记录映射到 映射到对象 方法用于执行表级别的操作,实例方法则用于执行针对 ,条记录的操作 在一 典型 RM 配置数据来 库端 程序 的映射关系,使用这些 M工具的程序员常常会发~:他们不得不忙于创建和维护 大堆的 L配置文件 Active Record Active rd il 用 的 RM 全遵 标准 射到 类.记录映射到对象,字段映射到对象属性.与其他大部分 M库的不同之处在于它 的配置方式它根据人们常用的命名惯例提供了很有意义的默认配置,因此,将需要开 发占编写的配置最降到了最低.为了证明这一点,下面就是一段 Active Record 写 的 用于包装 e r s表的程序 require 'active_record ' class Order < ActiveRecord ::Base end e r = Order.find(l) e r s c un = 0.5 e r class method 637 P"~ 635 "惜'''ll 64 eb It短2 ;10房Rails idfj lNMWeb lfJ !!N 该书下载自-书部落-分享计算机经典巨著!--www.shubulo.com!仅供试看^_^
该书下载自-书部落-分享计算机经典巨 18第2章Rai应用的架构 这段代码使用我们新建的 Order类来获取id为1的订单,并修改它的数量(在这里 我们省略了创建数据库连接所需的代码)。 Active Record减轻了我们处理底层数据库的 工作量,让我们能够更专注于业务逻辑 然而, Active record的威力还不止于此。从第53页开始,我们将开发一个“购物车” 应用程序,在那里你将看到 Active Record是如何天衣无缝地与 Rails框架的其他部分融 为一体的。如果一个web表单包含与业务对象相关的数据,那么 Active Record可以将其 抽取出来、填入模型对象。 Active Record还支持复杂的模型数据验证,如果表单数据不 能通过验证,只需编写一行代码,就可以在 Rails视图中获取并格式化显示错误信息。 在Rail的MvC架构中, Active Record是“模型”这一部分坚实的基础。这也正是 我们为什么要专门用三章篇幅(从第281页起)来介绍它的原因。 23 Action pack:视图与控制器 Action Pack: The View and Controller 在MVC架构中,视图与控制器是密不可分的:控制器为视图提供数据,然后又接 收来自页面的事件—这页面正是由视图生成的。正因为有如此密切的交互,在Rail 中对视图和控制器的支持被捆绑在同一个组件中,那就是 Action Pack。 不过,不要因为 Action Pack是一个组件,就认为 Rails应用程序中的视图代码与控 制器代码会搅在一起。恰恰相反, Rails给你提供了编写web应用时必需的隔离,清晰地 将控制逻辑与表现逻辑区分开来。 视图支持 View Support 在Rals中,视图负责创建将要在浏览器上显示的页面可能是整个页面,也可 能是其中的一部分。在最简单的情况下,视图就是一堆HTML代码,用于显示固定的文 本。不过,一般来说,你都需要在视图中加入一些动态内容这些动态内容通常是控 制器中的 action方法制造的。 在 Rails中,动态内容是由模板生成的。模板的形式有三种,其中最常用的是 rhm:用一个名为ERb(或者叫嵌入式Ruby, Embedded Ruby)的工具,将Ruby代码 片段嵌入到视图的HTML代码中。这种方式非常灵活,但一些纯粹主义者会认为它违 背了MVC的精神:由于视图中嵌入了代码,我们就有可能将原本应该放在模型或控制 3或者XML应答,或者Emal,或者别的什么东西。关键在于:视图负责生成给用户看的响应内容 对于用惯PHP或者JSP的wb开发者来说,这种做法应该很熟悉 Web开发敏捷之道一应用Rais进行敏捷Web开发,第2版
18 i l 的架 这段代码使用我们新建的 r类来获取 d为 1的订单,并修改它 数4«在这里. 我们省略了创建数据库连接所帘的代码) 0 Active ec 减轻 我们处理底 据库 工作量,让我们能够更专注于业务逻辑 然而. Active 还不止 页开始 发一个 物车 应用程序,在那里你将看到 ti Re ord 如何天衣无缝 Rai ls 框架 部分融 为-体的.如果一个 b表单包含与业务对象相关的数据 ,那么 ve e c ord 抽取出来、填入模型对象 Record 还支 数据验证 如 果 数据 能通过验证.只需编 一行代码,就可以在 s视图中获取并格式化显示错误信息 i l s的 C架构中. Active 部分坚 基础 我们为什么要专门用三章篇幅(从第 1页起)米介绍它的原因 2.3 Action Pack 图与 Action Pack: The View and Controller C架构中,视图与控制器是密不可分的:控制 为视同提供数据,然后又 收米自页丽的事件一一这页面正是由视图生成的。正因为布如此密切的交互,在 中对视图和控制器的支持被捆绑在同一个组件中.那就是 Packo 不过,不要因为 ti a c 组件 就认 ai ls 代码 制器代码会搅在一起.恰恰相反 ai 你提供 编写 eb 应用时必需的隔离,消晰地 将控制逻辑与表现逻辑区分开米 视图支持 View Support il s中 ,视剧负责创建将要在浏览器上显示的页而3一一可 是整个页面 也可 能是其中的一部分.在最简单的情况下,视阳就是一堆 L代码,用于显示固定的文 .不过.般来说.你都需要在视闺中加入一些动态内容 一这些动态内容通常是控 制器中的 ti n方法制造的 s中,动态内容是由模板生成的.模板的形式有三种 ,其中展常用的 rhtm/, )jj 一个名为 (或占叫嵌入式 Embedded Rub 工具 将Ruby 代码 片段嵌入到视阁的 L代码中 .这种方式非常灵活,但一些纯粹主义者会认为它 背丁 精神 代码 就有可能 原本 该放在模型或控 mai 成给用 户 响应 ·对 或者 这种 法应 该 WeblfJtlfH &l/#Ra ls fflfH Web 开发 JtN 该书下载自-书部落-分享计算机经典巨著!--www.shubulo.com!仅供试看^_^
该书下载自-书部落-分享计算机经典巨著!-www.shubulo.com!仅供试看^∧ 23 Action Pack:视图与控制器419 器中的逻辑放进视图。不过在我看来,这种批评是毫无根据的:即便在传统的MVC架 构中,视图也会包含程序代码。保持关注点的清晰分离原本就是开发者的职责,不应该 强求工具来确保这种分离(在第468页,第22.1节“ RHTML模板”中,我们将详细介 绍HTML模板) 第二种模板形式是rwml。借助这种视图模板,你可以用Ruby代码构造XML文档 生成的XML结构自动遵从代码的结构。我们将在第467页介绍rxml模板。 此外,Rals还提供了视图,用于在服务器端创建 JavaScript片段、并将其传递到 浏览器上执行。当创建Ajax界面时,这种视图会非常有用。我们将在第558页介绍is 视图。 还有…控制器 And the Controller Rails控制器是应用程序的逻辑中心,它负责协调用户、视图与模型之间的交互。不 过, Rails已经在幕后搞定了大部分的交互,你需要编写的代码都集中在应用层面的功能 上。因此,Rais的控制器非常容易开发和维护。 控制器还提供以下几种重要的辅助服务: 它负责将外部请求指引到内部 action,它所采用的URL命名规则对于普通人也同样 清晰易懂。 它负责管理缓存,这能给应用程序的性能带来数量级的提升。 它负责管理辅助模块,后者可以扩展视图模板的功能,而又不会让视图代 码膨胀 ·它负责管理 session,让用户感觉仿佛是在与我们的应用程序进行持续不断的交互。 关于 Rails还有很多可说的。不过,与其挨个介绍它的组件,还不如让我们卷起袖 子,来写一些可以工作的应用。在下一章,我们首先安装Rail,然后写一些简单的东西 只是为了确认一切都安装正确。在第5章“ Depot应用程序”(第53页)中,我们要 来编写一点更实在的东西:一个简单的在线商店应用。 Web开发敏捷之道一应用Ra进行敏捷Web开发,第2版
2.3 Action Pack 器中的逻辑放进视阁 。不过在我看米,这种批评是毫无根据的 即使在传统 构中 ,视图也会包含程序代码.保持关注点的清晰分离原本就是开发者 职责, 不应该 强求 具来确保这种分离 (在第 8页,第 HT 二种模板形式是 o借助这种视阳模板,你可以用 y代码构造 一一生成的 L结构自动遵从代码的结 们将在第 7页介绍 rx 模板 此外 还提 于在 器端创建Ja aS ript 将其 器上执行.当创建 界丽时 会非常有 将在 5 5 页介 rj 视阁 还青......控制器 And the Controller I 间 的交互 过, ail 在幕后搞 大部分 交互 你需要 代码都 功能 .闵此 il 制器 常容 控制器还提供以下儿种重要的辅助服务 外部请求 ti on 用 的 UR 命名 通人 晰易↑币 • 1::负责管理缓存,这能给应用程序的性能带来数量 提升 管理 助技 扩展视 模板 功能 不会让视 用 户 佛是 程序进行持续不断的 关于 s还有很多可说的.不过,与其挨个介绍它 还不如让我 卷起 ,米写 些可以工竹的应用 .在下一章 们首先安 .然后写一些 选、西 一一只是为了确认一切都安装正确.在第 5章 pot应用程序.. 5 3 来编 ←点更实在的东西 一个简单的在线商店应用 Web /f6t/iit.应2 1JJb il H. J!N 该书下载自-书部落-分享计算机经典巨著!--www.shubulo.com!仅供试看^_^
第3章 安装 Rails Installing Rails 写这种书通常都会选择“平稳起步”的方式:从一些比较简单的东西开始,逐渐过 渡到高阶的内容。这样一来,当读者在书店里随手翻阅时,他会觉得“这些东西还挺简 单”;直到他把书买回了家,那些真正的难题才开始折磨他 我们这本书并非如此。因为 Rails实在很简单,所以本章很可能是全书中最难的一章 没错,也就是关于“如何在你的电脑上把Rail环境跑起来”的一章。 不过别害怕,这也不是真的那么难,无非是要在机器上安装一个专业品质的web开 发工具,而这个工具又用到了别的一些组件而已。另外,由于各个操作系统对web服务 器等开发工具的支持有所不同,本章内容也分为几个小节,分别针对 Windows、Mac和 Unⅸx用户(别担心,从这一章往后,所有的操作系统都将被 Rails隔离在背后了) Mike Clark和 Dave Thomas曾经做过一系列的 Rails讲座,教那些从未用过Rals和 Ruby的人用它们来编写应用程序。本章的内容就来自我们从这些讲座中获得的经验 我们一直努力让初学者快速而轻松地完成安装过程。 另外你会发现,本章介绍的内容与网上的文档有所不同。这是因为世界一直在飞快 地改变,印在书上的详细介绍很可能已经过时了。 3.1购物清单 Your Shopping List 为了让 rails跑起来,你需要下列东西: 一个Ruby解释器。 Rails是用Ruby写的,你的应用程序也要用Ruby来写。目前 Rai开发团队推荐的Ruby版本是1.84版。(截至2006年10月,Ruby的最新版 http://pragmaticstudio.com Wb开发敏捷之道—应用 Rails进行敏捷Web开发,第2版
安装 Installing Rails 写这种书通常都会选 "平稳起 "的方式:从一些比较简单的东西开始,逐渐过 波圭 读者在 店里随手 西还 单..直到他把书买回了家,那些真正的难题才开始忻前 找们这本书并非如此。因为 s实在很简单,所以本章很可能是全书中最难的 一一没错.也就是关于"如何在你的电脑上把 i l s环挽跑起来"的一章 不过别害怕,这也不是真的那么难,无非足要在机器上安装一个专业品质 b开 工具,而这个工具又用到了 的些组件而已。另外,由于各个操作系 服务 器等开发工具的支持有所 本章内容也分为几个小节 ,分 针对 do 这一章 ls Mike ar Dav Thoma 做过 的Rail 从未 过Rail Ruby 程序 容 就 们从这 -一我们一直努力让初学者快速而轻松地完成安装过程 另外你会发现,本章介绍的内容与网上的文档有所不同.这是因为世界一直在飞快 地改变,印在书上的详细介绍很可能 经过时了 3·1 物清单 Your Shopping List 为了让 s跑起来,你需要下列尔 i l 用R 也要用Rub il 团队 的Ru 1. .4 10 ub I ht t p: / /pragmat i cst udi o . com Web JfJtIN il! 0, il eb !f. 1tN