Agile Web Development with 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 %>


 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值