Agile Web Development with Rails 翻译(十七)

本文介绍了如何在Rails应用中实现结算功能,包括创建订单表、更新商品项目表、处理订单详情及构建表单等步骤。

Agile Web Development with Rails 翻译(十七)

第九章 任务 D: 结算!

 

 

迄今为止,我们已经建立了一个基本的产品管理系统,我们实现一个分类目录,并有一个很好看的商店购物车。现在我们需要让买方能够真正地用购物车中购买些东西。再继续之前让我们先实现结算功能。

 

我们不打算走太远。目前我们所要做的是获取用户的联系细节和付款方式。利用这些我们将在数据库中构建一个订单。顺着它我们可以多看看model,确认,表单处理以及组件。

 

----------------------------------------------------------

Joe . . .

信用卡的处理在哪儿?

 

在这一点上,我们的教程应用程序与事实有些脱离。现实中,我们或许需要我们的应用程序能处理商业付款。我们可能甚至想整合信用卡处理(或许使用Payment模块)。但是,整合一个付款处理系统要求很多人的工作和至始至终的工作。这会转移我们对Rails的注意力,所以我们继续这个不完全的练习。

----------------------------------------------------------------

 

9.1 Iteration D1: 捕获定单

 

订单是一组商品项目,与购买交易的细节。我们已经有了商品项目--当我们在前一章创建购物车时我们已经定义了它们。我们还没有用于保存订单的表。基于47页的图表,并且与客户简单交流之后,我们可以创建orders表。

create table orders (

id int not null auto_increment,

name varchar(100) not null,

email varchar(255) not null,

address text not null,

pay_type char(10) not null,

primary key (id)

);

我们知道当我们创建新订单时,它必然要和一个或多个商品项目联系在一起。在数据库术语中,这意味着我们需要从line_items表到orders表增加一个外键引用,所以我们利用这个机会来也更新line itemsDDL(查看487页的create.sql清单,看看如何添加drop table语句。)

create table line_items (

id int not null auto_increment,

product_id int not null,

order_id int not null,

quantity int not null default 0,

unit_price decimal(10,2) not null,

constraint fk_items_product foreign key (product_id) references products(id),

constraint fk_items_order foreign key (order_id) references orders(id),

primary key (id)

);

记得更新这个计划(这会清空你数据库内包含的所有数据)并使用Rails的产生器来创建Order model。我们没有重新生成line itemsmodel,因为目前这个很好。

depot> mysql depot_development <db/create.sql

depot> ruby script/generate model Order

这告诉数据库外键的事。这是件好事,因为许多数据库都将检查外键约束,以保持我们的代码的正确性。但我们同样要告诉Rails一个定单有很多商品项目,并且一个商品项目属于一个定单。首先,我们打开app/models目录下新创建的order.rb文件,并添加一个对has_many()的调用。

class Order < ActiveRecord::Base

has_many :line_items

end

下面,我们指定一个反向的链接,在line_item.rb文件中添加belongs_to()方法的调用(记住在我们设置cart时已经声明一个line item属于一个product)

class LineItem < ActiveRecord::Base

belongs_to :product

belongs_to :order

# . . .

我们还需要一个action来处理获取订单详情。在前一章我们在cart view中设置了一个链接给称为checkout的动作,所以现在我们必须在store controller中实现一个checkout()方法。

def checkout

@cart = find_cart

@items = @cart.items

if @items.empty?

redirect_to_index("There's nothing in your cart!")

else

@order = Order.new

end

end

注意我们如何首先检查以确保购物车中有东西。这阻止人们直接通过导航到达付款操作,并创建一个空的订单。

假设我们已经有了一个有效的cart,我们创建个新Order对象以用来填充view。注意这个order还没有保存到数据库--它只是用view来组装checkout表单。

Checkout viewapp/views/store目录下的checkout.rhtml文件内。让我们构建些简单的东西来展示如何将表单数据和Rails model对象联系起来。然后我们添加确认和错误处理,对于Rails来说,以基本与重复开始有助于使事情变得容易。

 

 

Rails 和表单

 

Rails对从关系数据库获取数据并将其传入到Ruby对象中提供了强大的支持。所以你也期望,在model 对象和用户的浏览器之间传递数据,它也有同样的支持。

我们已经看到了这个例子。当我们创建我们的产品管理controller时,我们使用scaffold generator创建一个表单以为新产品获得所有数据。如果你查看那个view的代码(app/views/admin/new.rhtml),你将看到下面内容:

<h1>New product</h1>

<%= start_form_tag :action => 'create' %>

<%= render_partial "form" %>

<%= submit_tag "Create" %>

<%= end_form_tag %>

<%= link_to 'Back', :action => 'list' %>

这涉及到使用render_partial('form')的子表单。[render_partial( ) is a deprecated form of render(:partial=>...). The scaffold generators had not been updated to create code using the newer form at the time this book was written.]在文件_form.rhtml中的该子表单可获取产品的有关信息:

<%= error_messages_for 'product' %>

<!--[form:product]-->

<p><label for="product_title">Title</label><br/>

<%= text_field 'product', 'title' %></p>

<p><label for="product_description">Description</label><br/>

<%= text_area 'product', 'description', :rows => 5 %></p>

<p><label for="product_image_url">Image url</label><br/>

<%= text_field 'product', 'image_url' %></p>

<p><label for="product_price">Price</label><br/>

<%= text_field 'product', 'price' %></p>

<p><label for="product_date_available">Date available</label><br/>

<%= datetime_select 'product', 'date_available' %></p>

<!--[eoform:product]-->

我们也可以使用scaffold generator来为orders表创建一个表单,但是Rails生成的表单并不总是那么漂亮。我们要生成一些更好看的。让我们在创建我们自己的数据输入表单之前,更多地了解那些自动生成表单的方法。

Rails对于所有那些标准的HTML输入标记都有对应的model相关的helper方法。例如,我们需要创建一个HTML<input>标记来允许买者输入他们的名字。在Rails中,我们可以在view中写出如下语句:

<%= text_field("order", "name", :size => 40 ) %>

这里,text_field()将创建一个带有type="text"HTML <input>标记。这个的语句会用@order model内的name字段的内容组装那个字段。甚至当最终用户最后提交表单时,model能够获取浏览器响应给这个字段的新值,并保存它,然后在需要时写入数据库。

有很多用于表单的helper 方法(我们将在332页详细讨论)。除了text_field(),我们可以使用text_area()来获取买者的地址,并用select()来创建一个付款方式的选择列表。

当然,为了让Rails从浏览器取得一个响应,我们需要将表单链接到Rails的动作上。我们可以通过指定一个链接给我们的applicationcontroller,和<form>标记的action=attribute内的动作来做到这点。但使用form_tag()方法更容易,另一个Rails helper方法也做同样的事。

因此,在有了这些背景资料后,我们准备创建获取定单信息的view。我们首先试试app/views/store目录中的checkout.rhtml文件。

<% @page_title = "Checkout" -%>

<%= start_form_tag(:action => "save_order") %>

<table>

<tr>

<td>Name:</td>

<td><%= text_field("order", "name", "size" => 40 ) %></td>

</tr>

<tr>

<td>EMail:</td>

<td><%= text_field("order", "email", "size" => 40 ) %></td>

</tr>

<tr valign="top">

<td>Address:</td>

<td><%= text_area("order", "address", "cols" => 40, "rows" => 5) %></td>

</tr>

<tr>

<td>Pay using:</td>

<td><%=

options = [["Select a payment option", ""]] + Order::PAYMENT_TYPES

select("order", "pay_type", options)

%></td>

</tr>

<tr>

<td></td>

<td><%= submit_tag(" CHECKOUT ") %></td>

</tr>

</table>

<%= end_form_tag %>


 
标题基于SpringCloud的分布式演唱会抢票系统研究AI更换标题第1章引言阐述该研究的背景、意义,介绍SpringCloud和分布式系统的相关性,以及本文的研究目标和方法。1.1研究背景与意义介绍当前抢票系统的现状和存在的问题,以及基于SpringCloud的分布式系统的优势。1.2国内外研究现状概述国内外在分布式抢票系统方面的研究情况和发展趋势。1.3研究目标和方法明确本文的研究目标,并阐述采用的研究方法和实验设计。第2章相关技术概述介绍SpringCloud框架以及分布式系统的基本原理和关键技术。2.1SpringCloud框架详细解释SpringCloud框架的组成、原理和功能特点。2.2分布式系统关键技术阐述分布式系统中的关键技术,如负载均衡、容错处理、服务注册与发现等。2.3演唱会抢票系统的技术需求分析演唱会抢票系统的技术需求和挑战,以及如何应用相关技术进行解决。第3章系统设计与实现详细描述基于SpringCloud的分布式演唱会抢票系统的设计和实现过程。3.1系统架构设计给出系统的整体架构设计,包括各个服务模块的划分和交互方式。3.2抢票服务设计详细介绍抢票服务的设计思路和实现方法,包括票务信息的存储和查询、抢票逻辑的处理等。3.3分布式事务处理阐述在分布式环境下如何处理事务,保证数据的一致性和完整性。第4章系统测试与优化对系统进行全面的测试,包括性能测试、安全性测试等,并针对测试结果进行优化。4.1测试环境与方法介绍测试环境的搭建和测试方法的选择,以及如何模拟高并发场景进行测试。4.2测试结果分析对测试结果进行详细分析,包括系统的响应时间、吞吐量、错误率等指标。4.3系统优化策略根据测试结果提出针对性的优化策略,提高系统的性能和稳定性。第5章结论与展望总结本文的研究成果,分析系统的优缺点,并展望未来的研究方向和应用前景。5.1研究结论概括本文的主要研究内容
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值