您的位置:首页 > 产品设计 > 产品经理

Agile Web Development with Rails 翻译(三)

2006-09-11 14:36 405 查看
Agile Web Development with Rails 翻译(三)

尽管它不会马上明白你用于访问它们的SQL,但关系数据库实际上被设计成精确的理论。这是一个很好的“视图”观点,它很难将关系数据库与面向对象的程序语言结合在一起。对象知道数据并操作它,数据库知道值的设置。很容易表述的相关术语在OO系统中有时候很难编码。反过来也是一样的。
过去,有用关系原则和OO观点进行它们的工作。让我们看看两个不同的方式。有人按数据库组织程序,有人按程序组织数据。

以数据库为中心的程序

首先有些人编写与数据库关联的代码,用C和COBOL语言。这些人典型地在它们代码中直接植入SQL语句,它们使用字符串或可对SQL进行转换的处理器在低级别上对数据库引擎进行调用。
这意味着很自然地将数据库逻辑与应用程序逻辑混纠在了一起。如果开发者想按次序排序和更新营业税,那么它写起来会相当地丑陋,如
EXEC SQL BEGIN DECLARE SECTION;
int id;
float amount;
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE c1 AS CURSOR FOR
select id, amount from orders;
while (1) {
float tax;
EXEC SQL WHENEVER NOT FOUND DO break;
EXEC SQL FETCH c1 INTO :id, :amount;
tax = calc_sales_tax(amount)
EXEC SQL UPDATE orders set tax = :tax where id = :id;
}
EXEC SQL CLOSE c1;
EXEC SQL COMMIT WORK;
不要怕,我们的代码不会这样的,即使在脚本语言如Perl和PHP中有这种程序风格。Ruby不是这样的。例如,我们可以使用Ruby的DBI库来产生看起来一样代码。(这个例子,像最后那个,也没错误检查。)
def update_sales_tax
update = @db.prepare("update orders set tax=? where id=?")
@db.select_all("select id, amount from orders") do |id, amount|
tax = calc_sales_tax(amount)
update.execute(tax, id)
end
end
这种方法是简洁的,易懂的,和广泛使用的。它看起来像是用于小应用程序的解决之道。但是,这不是个问题。混杂有商业逻辑和数据访问逻辑会使它在日后很难管理和扩展应用程序。在开始你的应用程序之前,您还要了解SQL。
从例子上来讲,我们的开发团体传来消息说,我们必须记录计算营业税的数据和时间。我们认为这很好解决。我们只是必须获取当前时间,这要添加一列给SQL的update语句,并传递时间给execute()调用。
但是假如我们在应用程序的多个不同地方设置了营业税会发生什么?现在我们需要检查并找出这些地方,更新每一处。我们有重复的代码,也就是我们有了个错误源(如果我们丢掉了一个地方的话)。
在正规语言中,通过包装对象来解决此类问题。我们已包装了每样东西在一个类中;我们已经将散落各地的重复更新到了一个地方。
有些人扩展了数据库程序这种思想。基本前提非常简单。我们包装对数据库的访问在一组类层次中。我们应用程序的其余部分使用这些类和它们的对象—它从不与数据库直接交互。这种方式我们包装所有材料在单独的层中,并减少我们应用程序代码从低层细节上对数据库的访问的影响。在修改我们营业税这种情况下,我们只是简单地修改被包装的定单表的类,并在营业税被修改后来更新时间戳。
实际上,这个概念实现起来要困难一些。真实的数据库表互相间有联系的,我们想在我们对象中映像这些联系:定单对象应该是包含商品项目对象的集合。然后我们启动对象导航,执行,和数据连结。这些表面看来很复杂, 当面对这些复杂时,行业总是要这样做:它发明了了三个字母:ORM,Object/Relational Mapping。Rails使用ORM。

对象与关系映射(Object/Relational Mapping)

ORM库映射数据库的表到类。如果数据库有个表叫orders,我们的程序将有个类叫Order。表内的行对应于类的对象—一个特定的定单表示为类Order的一个对象。对象内的属性被用来设置或读取单个列。我们的Order对象有方法来获取和设置总量,营业税等等。
此外,Rails中包装我们数据库表的类提供了一套类级别的方法来完成表级别的操作。例如,我们可能需要寻找一个特定id的定单。这是做为一个类方法来实现的,它返回相应的Order对象。在Ruby代码中,这看起来像这样。
order = Order.find(1)
puts "Order #{order.customer_id}, amount=#{order.amount}"
有时候这些类级别方法返回对象的集合。
Order.find(:all, :conditions => "name='dave'") do |order|
puts order.amount
end
最后,对应于表内各个行的对象有在这个行上操作的方法。或许用的最多的是save(),这个操作会将行保存回数据库。
Order.find(:all, :conditions => "name='dave'") do |order|
order.discount = 0.5
order.save
end
所以一个ORM层映射表到类,行到对象,列到这些对象的属性。类方法被用于表级别上操作,实例方法完成单个行上的操作。

在一个典型的ORM库中,你提供配置数据给数据库和程序内的映射。程序员通常使用这些ORM工具来找出它们自己创建并管理的一大堆XML配置文件。

“活动记录”(Active Record)

“活动记录”是由Rails支持的ORM层。它很接近标准的ORM模型:表映射类,行映射对象,列映射对象属性。它与其它ORM库的区别是它配置的方式。通过约定和启动的缺省值,“活动记录”最小化要开发者完成的配置的数量。为了说明这些,这儿是个使用了“活动记录”来包装我们的orders表的程序。
require 'active_record'
class Order < ActiveRecord::Base
end
order = Order.find(1)
order.discount = 0.5
order.save
这段代码使用一个新的Order类来捕获id为1的订单并修改它的折扣。(我们忽略了创建数据库连接的代码。)“活动记录”减轻了我们处理数据库的负担,让我们有更多的时间来关心商业逻辑。
但是“活动记录”的作用不止是这些。就像你在43页看到的,当我们开发购物车应用程序时,“活动记录”会整合Rails框架的余下部分。如果Web表格包含的数据关联到一个商业对象。“活动记录”可以抽取它到我们“模型”中。“活动记录”支持对表格数据的确认,如果表格数据确认失败,Rails的“视图”可以抽取和格式化错误在一行代码内。
“活动记录”是Rails的MVC体系的,可靠的模型基础。这也是为什么我们会拿出两章来讨论它。

2.3 “活动包“(Action Pack): “视图”和“控制器”

MVC的“视图”和“控制器”部分的关系是紧密的。“控制器”提供数据给“视图”,“控制器”接受来自于“视图”生成的页面内的事件。因为这种相互作用,Rails内对“视图”和“控制器”的支持被绑到了一个单独的组件内,“活动包”。
不要想像由于“活动包”是单个组件,你的应用程序“视图”代码和“控制器”代码就会乱七八糟的。正相反,Rails会让你按你的需要分别地,清晰地,写出用于控制和表现逻辑的代码。

对“视图”的支持

在Rials中,“视图”用于创建所有或部分要显示在浏览器内的页面[或者是个XML请求,或是一个邮件,或…。关键是“视图”能生成对用户的响应。]它是最简单的,“视图”是显示一组固定文本的HTML代码。大多数典型情况是你想用它包含由“控制器”内“动作”方法生成的动态内容。
在Rails中,动态内容由模板生成,它有两种风格。一种是在“视图”的HTML内使用Ruby工具ERb(或Embedded Ruby)植入Ruby代码片断[这种途径对使用PHP或Java的JSP技术开发Web工作的人很熟悉。]这种途径很灵活,但有些人会抗议说这违反了MVC的精神。在“视图”内植入代码会有将应该在“模型”或“控制器”内的逻辑添加到“视图”的危险。维持概念的清晰和分离是开发者的工作(我们可看看17.3节的HTML模板,和330页的RHTML模板。)
Rails也支持构建风格的“视图”。这些可让你使用Ruby代码来构建XML文档—生成XML的结构会被自动遵循代码结构。我们在329页讨论“构建模板”(builder templates)。

“控制器”的其它作用!

Rails的“控制器”是应用程序的逻辑中心。它用于协调用户,“视图”和“模型”之间的相互关系。但是,Rails的处理大多数是隐藏在屏幕背后的;你写的代码只集中应用级别的功能上。这使得Rails的“控制器”代码非常易于开发和管理。
“控制器”还有些重要作用:
1、它将外部请求表现为内部“动作”。它能很好地处理对人友善的URL。
2、它管理缓冲管理器,它可以给应用程序进行排队。
3、它管理“帮助者”helper模块,它不用很多代码就能扩展了“视图”模板的能力。
4、它管理会话,给用户以正在与我们应用程序交互的印像。
这就是大部分Rails的工作。而不按组件来划分的,让我们卷起袖子来写些能工作的应用程序。下一章我们会安装Rails。在这之后是些简单的例子,这只是想确保每样东西都被正确安装了。在第五章,43页的Depot Application 中,我们将开始写些真东西—一个简单的在线商店应用程序。

2.2 “活动记录”(Active Record): 对Rails “模型”的支持

通常,我们希望我们的Web应用程序能保存它们信息在一个相关的数据库中。将按进入系统的次序存储次序,商品项目,和消费细节到数据库的表中。即使应用程序通常使用未结构化的文本,如weblog和新站点,通过也使用数据库存储来支持它们。
2006年4月16日更新
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: