Agile Web Development with Rails 翻译(十二 )

Agile Web Development with Rails 翻译(十二 )

第七章 任务 B: 分类显示目录

 

我们已经从客户那里收集了最初的要求,文档化了基本流程,并且处理了我们需要的数据,并为Depot应用程序的产品放置了管理页。

2006年4月17日更新


我们的下一个任务是创建分类显示目录

一旦我们的产品被安全地放到数据库中,就应该能简单地显示它们。这也是个基本的东西。

分类显示目录其实只是产品的另一种列表,所以我们开始吧!

 

7.1 循环 B1: 创建目录清单

 

回到56页,我们说过我们要为这个应用程序使用了两个“控制器”类。我们已经创建了Admin “控制器”,以便于卖方能够管理Depot应用程序。现在应该创建第二个“控制器”,它的目的是消费者。让我们称它为Store

depot> ruby script/generate controller Store index

 

上一章,我们使用generate工具来给products表创建个“支架”。这次,我们让它创建个新的“控制器”(StoreController),它包含一个“动作”方法,index()

为什么我们要选择第一个方法叫index呢?因为,就像大多数web服务,如果你调用一个Rails “控制器”并且没有明确地指定“动作”,Rails会自动地调用这个index动作。事实上,让我们试试它。在我们的浏览器中输入http://localhost:3000/store

 

 

 

它不会显示很多东西给我们,但至少我们知道有些东西被正确地调用了。本页面甚至告诉在哪儿找到程序文件来绘制这个页面。

让我们从简单地显示我们数据库中所有能销售的产品清单开始。哪么可销售产品由什么组成呢?我们的客户告诉我们,只要显示一个有效的日期或者是前一天的。

我们需要数据库之外得到产品清单,并使它可以在显示这个表的“视图”中被编码。这意味着我们必须修改store_controoler.rb内的index()方法。我们想在抽象级别编程,所以让我们假设我们可以要求“模型”能提供我们可以出售的产品清单。

def index

@products = Product.salable_items

end

很明显代码不会运行。我们需要在“模型”内的product.rb文件内定义方法salabel_items()。下面代码使用了Railsfind()方法。:all参数告诉Raisl,我们想匹配给出条件的所有行。(以后,条件检查条目的有效性数据。它使用MySQLnow()功能来取得当前的日期和时间。)我们要求我们的客户它应该有个对列表排序的选择,并且我们决定当第一次显示时应首先看到最新的产品,所以代码按date_available来降序排列。

# Return a list of products we can sell (which means they have to be

# available). Show the most recently available first.

def self.salable_items

find(:all,

:conditions => "date_available <= now()",

:order => "date_available desc")

end

find()方法返回包含一个Product对象的数组,此对象由从数据库返回的每一行组成。salable_items()方法简单地处理这个处理并返回给“控制器”。

现在我们需要写出“视图”模板。我们要在一个简单的表格中显示products表。要做到这点,编辑app/views/store/index.rhtml文件。(记住“视图”的路径名由“控制器”(store)和“动作”(index)的名字构成。.rhtml部分表示它是个ERb模板。)

<table cellpadding="5" cellspacing="0">

<% for product in @products %>

<tr valign="top">

<td>

<img src="<%= product.image_url %>"/>

</td>

<td width="450">

<h3><%=h product.title %></h3>

<small>

<%= product.description %>

</small>

<br/>

<strong>$<%= sprintf("% 0.2f", product.price) %></strong>

<%= link_to 'Add to Cart',

:action => 'add_to_cart',

:id => product %>

<br/>

</td>

</tr>

<tr><td colspan="2"><hr/></td></tr>

<% end %>

</table>

刷新页会显示图7.1,我们找来客户,它们相满意。毕竟,我们已完成一个目录,而这只用了几分钟。但是我们在让自己满意之前,客户至少还需要在顶部有个带有linksnews的工具条。

在真实世界里遇到这样的情况,我们也许会召集设计人员--我们都已经看到了太多程序员设计的自以为不错的网站,却在折磨世界上的其他人们。但是团队的web设计者正在休假,并在某处寻求灵感,直到明年才会回来,因此,现在让我们担起这样的责任吧。这是开始另一轮循环的时候了。

 

 

 

 

 

 

 

 

7.2 Iteration B2: 给页面添加装饰

 

一个特定的web站点的页典型地共享一个类似的层设计会创建一个标准的模板用于替换相应的内容。我们的任务是添加这个页面装饰给每个store内的页面。

幸运地,在Rails内我们可以定义“层”(layout)。“层”是个模板,我们可以按顺序向其内添加内容。在我们的例子中,我们可以定义一个单独的“层”,用它来存储所的页面并将目录页面也放到这个“层”中。稍后我们可以对购物车和付款页面做同样的事情。因为只有一个“层”,我们可以通过添加些东西来修改我们站点入口的外观和感应。在每行内放置个支持物感觉可能更好些,我们也可以修改它。

Rails中有很多使用“层”的特殊方式。我们为行选择最简单的一种。如果你创建了一个“模板”文件在目录app/views/layouts中且带有与“控制器”同样的名字的话,缺省地所有“视图”都会通过“控制器”来使用这个“层”。所以让我们现在创建一个。我们的“控制器”叫store,所以我们将命名“层”为store.rhtml

Line 1 <html>

- <head>

- <title>Pragprog Books Online Store</title>

- <%= stylesheet_link_tag "depot", :media => "all" %>

5 </head>

- <body>

- <div id="banner">

- <img src="/images/logo.png"/> ||

- <%= @page_title || "Pragmatic Bookshelf" %>

10 </div>

- <div id="columns">

- <div id="side">

- <a href="http://www....">Home</a><br />

- <a href="http://www..../faq">Questions</a><br />

15 <a href="http://www..../news">News</a><br />

- <a href="http://www..../contact">Contact</a><br />

- </div>

- <div id="main">

- <%= @content_for_layout %>

20 </div>

- </div>

- </body>

- </html>

除了使用了HTML构件外,这个“层”有三个Rails特定条目。第四行使用了一个Rails “帮助者”方法来生成一个<link>标记给我们的depot.css 样式表。第九行我们设置变量@page_title的值为页标题。但是真正的魔术是从第十九行开始的。Rails自动地设置变量@content_for_layoutpage-specific 内容--通过这个请求的“视图”调用来产生东西。在我们的例子中,这将是由index.rhtml生成分类页面。

我们也借这个机会来整理app/views目录内的index.rhtml文件。

<% for product in @products %>

<div class="catalogentry">

<img src="<%= product.image_url %>"/>

<h3><%= h(product.title) %></h3>

<%= product.description %>

<span class="catalogprice"><%= sprintf("$% 0.2f", product.price) %></span>

<%= link_to 'Add to Cart',

{:action => 'add_to_cart', :id => product },

:class => 'addtocart' %><br/>

</div>

<div class="separator">&nbsp;</div>

<% end %>

<%= link_to "Show my cart", :action => "display_cart" %>

注意我们是如何切换到<div>标记的,并添加CSS类名字给与输出页关联的标记的。为了让给出的Add to Cart连接到一个类,我们必须使用link_to()方法可选的第三个参数,它让我们给生成的标记指定HTML属性。

 

 

 

 

 

 

 

 

为了让这些都能工作,我们需要组合它们在一个快速的样式表内(或者找个现在的样式表修改一下)。文件 depot.css 出现在目录public/stylesheets中。 (508页有样式表清单。)刷新浏览器窗口可看到图72.画面。它显示我们最终的页面应该与它差不多。

 

我们刚刚做了些什么

 

我们已经将基本的store的分类目录显示放到了一些。步骤是:

1、创建个新的“控制器”来控制用户交互。

2、实现缺省的index()“动作”。

3、添加一个类方法给Product “模型”来返回可销售项目。

4、实现了一个“视图”(一个.rhtml文件)并添加“层”来包含它(另一个.rhtml文件)

5、创建最简单的样式表。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值