在上次的内容里,我们完成了订单的编写。这次我们模拟一个简单的送货页面,给这个购物车的管理员用。
1. 首先,我们修改order表,给他添加一个字段shipped_at:
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,
shipped_at datetime null,
primary key (id)
);
2. 添加一个Action,在admin_controller.rb文件中添加一个方法:
def ship
@pending_orders = Order.pending_shipping
end
3. 给order的model实现pending_shipping方法:
def self.pending_shipping
find(:all, :conditions => "shipped_at is null")
end
4. 还是老道路,M有了,C有了,还差个V,现在来补上:
在Views的admin目录下,创建一个ship.rhtml文件,内容如下:
<h1>Orders To Be Shipped</h1>
<%= form_tag(:action => "ship") %>
<table cellpadding="5" cellspacing="0">
<%= render(:partial => "order_line", :collection => @pending_orders) %>
</table>
<br />
<input type="submit" value=" SHIP CHECKED ITEMS " />
<%= end_form_tag %>
<br>
注意兰色的一行,参数partial指明了一个局部的模板,collection参数指定了使用的数据的集合,这里是pending_orders方法取出的order。如果不明白(其实我自己也不明白J),先不着急,等下看看效果图就好了。
5. 下面,我们还要再进行一步,实现上面调用的order_line这个页面,还是在Views的admin目录下,创建一个_order_line.rhtml文件,作为约定,文件名使用“_”作为前缀。文件内容如下:
<tr valign="top">
<td class="olnamebox">
<div class="olname"><%= h(order_line.name) %></div>
<div class="oladdress"><%= h(order_line.address) %></div>
</td>
<td class="olitembox">
<% order_line.line_items.each do |li| %>
<div class="olitem">
<span class="olitemqty"><%= li.quantity %></span>
<span class="olitemtitle"><%= li.product.title %></span>
</div>
<% end %>
</td>
<td>
<%= check_box("to_be_shipped", order_line.id, {}, "yes", "no") %>
</td>
</tr>
6. 看看效果图:
7. 当然,上面的效果还不是很好看,我们要美化下,修改Views的layouts目录下的admin.rhtml文件:
<html>
<head>
<title>ADMINISTER Pragprog Books Online Store</title>
<%= stylesheet_link_tag "scaffold", "depot", "admin", :media => "all" %>
</head>
<body>
<div id="banner">
<%= @page_title || "Administer Bookshelf" %>
</div>
<div id="columns">
<div id="side">
<%= link_to("Products", :action => "list") %>
<%= link_to("Shipping", :action => "ship") %>
</div>
<div id="main">
<% if @flash[:notice] -%>
<div id="notice"><%= @flash[:notice] %></div>
<% end -%>
<%= @content_for_layout %>
</div>
</div>
</body>
</html>
再来看看效果:
8. 接下来我们要实现“SHIP CHECKED ITEMS”按钮的功能。修改admin_controller.rb文件,添加下面的代码:
def ship
count = 0
if things_to_ship = params[:to_be_shipped]
count = do_shipping(things_to_ship)
if count > 0
count_text = pluralize(count, "order")
flash.now[:notice] = "#{count_text} marked as shipped"
end
end
@pending_orders = Order.pending_shipping
end
private
def do_shipping(things_to_ship)
count = 0
things_to_ship.each do |order_id, do_it|
if do_it == "yes"
order = Order.find(order_id)
order.mark_as_shipped
order.save
count += 1
end
end
count
end
def pluralize(count, noun)
case count
when 0: "No #{noun.pluralize}"
when 1: "One #{noun}"
else "#{count} #{noun.pluralize}"
end
end
再给order.rb文件中添加代码:
def mark_as_shipped
self.shipped_at = Time.now
end
这时候选中页面上的Check框,再点击按钮以后,会出现类似下面的效果:
OK,这次就到这里,目前为止我也仅仅还是从书本上拷贝代码,有很多细节还不清楚。后面争取有自己的理解写出来。