- 浏览: 304198 次
- 性别:
- 来自: 江阴
文章分类
最新评论
我用的 Rails 和 Ruby 的版本:
D:\work\depot>rails -v
Rails 1.2.6
D:\work\depot>ruby -v
ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]
第六章 任务A 货品维护
rails depot
ruby script/server scaffold Product Admin
ruby script/server
http://localhost:3000/admin
depot 数据库的脚本
D:\work>mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 12 to server version: 5.0.27-community-nt
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
建立数据库:
create database depot_development;
create database depot_test;
create database depot_production;
D:\work\depot>mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 7 to server version: 5.0.27-community-nt
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> grant all on depot_development.* to 'root'@'localhost';
Query OK, 0 rows affected (0.00 sec)
mysql> grant all on depot_test.* to 'root'@'localhost';
Query OK, 0 rows affected (0.00 sec)
mysql> grant all on depot_production.* to 'root'@'localhost';
Query OK, 0 rows affected (0.00 sec)
删除数据库:
drop database depot_development;
drop database depot_test;
drop database depot_production;
mysql> use mysql
Database changed
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| depot_development |
| depot_production |
| depot_test |
| mysql |
+--------------------+
5 rows in set (0.00 sec)
mysql> drop database depot_development;
Query OK, 1 row affected (0.06 sec)
mysql> drop database depot_test;
Query OK, 0 rows affected (0.00 sec)
mysql> drop database depot_production;
Query OK, 0 rows affected (0.00 sec)
mysql>
显示所有数据库:
show databases;
选择数据库:
use depot_development
mysql> use depot_development
Database changed
mysql> use mysql
Database changed
mysql> use depot_development; 这个地方可要';' 也可不要';'
Database changed
显示所有表:
show tables;
创建货品表(create_0.sql 的内容):
drop table if exists products;
create table products (
id int not null auto_increment,
title varchar(100) not null,
description text not null,
image_url varchar(200) not null,
price decimal(10,2) not null,
primary key(id)
);
执行 SQL 语句:
建表:
mysql depot_development <db/create.sql
删除表中数据:
mysql> delete from products;
Query OK, 4 rows affected (0.03 sec)
D:\work\depot>mysql depot_development <db/create.sql (没有指定用户出错了)
ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' (using password: NO)
D:\work\depot>mysql -u root depot_development <db/create.sql
D:\work\depot>mysql -u root depot_development <db/product_data.sql (导入数据)
D:\work\depot>mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 10 to server version: 5.0.27-community-nt
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> use depot_development
Database changed
mysql> show tables;
+-----------------------------+
| Tables_in_depot_development |
+-----------------------------+
| products |
+-----------------------------+
1 row in set (0.00 sec)
mysql> select * from products;
Empty set (0.00 sec)
mysql>
添加缺失的字段 :
alter table products add column date_available datetime; 这个是以前老的方法,不建议采用
创建货品表(create_1.sql 的内容):
drop table if exists products;
create table products (
id int not null auto_increment,
title varchar(100) not null,
description text not null,
image_url varchar(200) not null,
price decimal(10,2) not null,
date_available datetime not null,
primary key(id)
);
product.rb
D:\work\depot\app\views\admin\list.rhtml
修改样式文件
D:\work\depot\public\stylesheets\scaffold.css
新增货品的时候输入的图片地址
http://localhost:3000/images/svn.JPG
http://localhost:3000/images/utc.jpg
http://localhost:3000/images/auto.jpg
第七章 任务B 分类显示
ruby script/generate controller Store index
D:\work\depot\app\controllers\store_controller.rb
D:\work\depot\app\models\product.rb
D:\work\depot\app\views\store\index.rhtml
D:\work\depot\app\views\layouts\store.rhtml
D:\work\depot\app\views\store\index.rhtml
D:\work\depot\public\stylesheets\depot.css
第八章 任务C: 创建购物车
D:\work\depot\app\controllers\store_controller.rb
D:\work\depot\db\product_data.sql
D:\work\depot>mysql -u root depot_development <db/product_data.sql (导入数据)
下面说明在mysql中 exit 和 quit 命令都可以退出 mysql
D:\work\depot>mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 41 to server version: 5.0.27-community-nt
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> use depot_development
Database changed
mysql> delete from products;
Query OK, 3 rows affected (0.05 sec)
mysql> exit
Bye
D:\work\depot>mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 42 to server version: 5.0.27-community-nt
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> quit
Bye
D:\work\depot>
D:\work\depot>ruby script/generate model LineItem
D:\work\depot\app\models\line_item.rb
D:\work\depot\app\controllers\store_controller.rb
D:\work\depot\app\models\cart.rb
D:\work\depot\app\models\line_item.rb
D:\work\depot\app\controllers\store_controller.rb
D:\work\depot\app\views\store\display_cart.rhtml
D:\work\depot\app\controllers\application.rb
D:\work\depot\app\views\store\display_cart.rhtml
D:\work\depot\app\models\cart.rb
美化购物车
D:\work\depot\app\views\store\display_cart.rhtml
处理错误
D:\work\depot\app\controllers\store_controller.rb
D:\work\depot\log\development.log
D:\work\depot\app\views\layouts\store.rhtml
D:\work\depot\app\controllers\store_controller.rb
D:\work\depot\app\views\store\display_cart.rhtml
完成购物车
D:\work\depot\app\controllers\store_controller.rb
D:\work\depot\app\models\cart.rb
D:\work\depot\app\controllers\store_controller.rb
D:\work\depot\app\models\cart.rb
辅助方法
D:\work\depot\app\helpers\application_helper.rb
D:\work\depot\app\views\store\display_cart.rhtml
D:\work\depot\app\views\store\index.rhtml
第九章 任务D: 结账
D:\work\depot\db\create.sql
D:\work\depot\app\models\order.rb
D:\work\depot\app\models\line_item.rb
D:\work\depot\app\controllers\store_controller.rb
D:\work\depot\app\views\store\checkout.rhtml
D:\work\depot\app\models\order.rb
D:\work\depot\app\controllers\store_controller.rb
D:\work\depot\app\models\order.rb
D:\work\depot\app\views\layouts\store.rhtml
mysql> select * from orders;
+----+------+---------------+----------------+----------+
| id | name | email | address | pay_type |
+----+------+---------------+----------------+----------+
| 3 | aaaa | bbbb@aaaa.com | aaaa bbbb cccc | cc |
+----+------+---------------+----------------+----------+
1 row in set (0.00 sec)
mysql> select * from line_items;
+----+------------+----------+----------+------------+
| id | product_id | order_id | quantity | unit_price |
+----+------------+----------+----------+------------+
| 1 | 1 | 3 | 1 | 29.95 |
| 2 | 2 | 3 | 1 | 29.95 |
| 3 | 3 | 3 | 1 | 29.95 |
+----+------------+----------+----------+------------+
3 rows in set (0.00 sec)
迭代D2: 在付账页面显示购物车内容
D:\work\depot\app\views\store\checkout.rhtml
D:\work\depot\app\views\store\checkout.rhtml
D:\work\depot\app\controllers\store_controller.rb
修改如下方法:
D:\work\depot\app\views\store\display_cart.rhtml
D:\work\depot\app\views\store\checkout.rhtml
D:\work\depot>rails -v
Rails 1.2.6
D:\work\depot>ruby -v
ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]
第六章 任务A 货品维护
rails depot
ruby script/server scaffold Product Admin
ruby script/server
http://localhost:3000/admin
depot 数据库的脚本
D:\work>mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 12 to server version: 5.0.27-community-nt
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
建立数据库:
create database depot_development;
create database depot_test;
create database depot_production;
D:\work\depot>mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 7 to server version: 5.0.27-community-nt
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> grant all on depot_development.* to 'root'@'localhost';
Query OK, 0 rows affected (0.00 sec)
mysql> grant all on depot_test.* to 'root'@'localhost';
Query OK, 0 rows affected (0.00 sec)
mysql> grant all on depot_production.* to 'root'@'localhost';
Query OK, 0 rows affected (0.00 sec)
删除数据库:
drop database depot_development;
drop database depot_test;
drop database depot_production;
mysql> use mysql
Database changed
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| depot_development |
| depot_production |
| depot_test |
| mysql |
+--------------------+
5 rows in set (0.00 sec)
mysql> drop database depot_development;
Query OK, 1 row affected (0.06 sec)
mysql> drop database depot_test;
Query OK, 0 rows affected (0.00 sec)
mysql> drop database depot_production;
Query OK, 0 rows affected (0.00 sec)
mysql>
显示所有数据库:
show databases;
选择数据库:
use depot_development
mysql> use depot_development
Database changed
mysql> use mysql
Database changed
mysql> use depot_development; 这个地方可要';' 也可不要';'
Database changed
显示所有表:
show tables;
创建货品表(create_0.sql 的内容):
drop table if exists products;
create table products (
id int not null auto_increment,
title varchar(100) not null,
description text not null,
image_url varchar(200) not null,
price decimal(10,2) not null,
primary key(id)
);
执行 SQL 语句:
建表:
mysql depot_development <db/create.sql
删除表中数据:
mysql> delete from products;
Query OK, 4 rows affected (0.03 sec)
D:\work\depot>mysql depot_development <db/create.sql (没有指定用户出错了)
ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' (using password: NO)
D:\work\depot>mysql -u root depot_development <db/create.sql
D:\work\depot>mysql -u root depot_development <db/product_data.sql (导入数据)
D:\work\depot>mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 10 to server version: 5.0.27-community-nt
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> use depot_development
Database changed
mysql> show tables;
+-----------------------------+
| Tables_in_depot_development |
+-----------------------------+
| products |
+-----------------------------+
1 row in set (0.00 sec)
mysql> select * from products;
Empty set (0.00 sec)
mysql>
添加缺失的字段 :
alter table products add column date_available datetime; 这个是以前老的方法,不建议采用
创建货品表(create_1.sql 的内容):
drop table if exists products;
create table products (
id int not null auto_increment,
title varchar(100) not null,
description text not null,
image_url varchar(200) not null,
price decimal(10,2) not null,
date_available datetime not null,
primary key(id)
);
product.rb
class Product < ActiveRecord::Base validates_presence_of :title, :description, :image_url validates_numericality_of :price validates_uniqueness_of :title validates_format_of :image_url, :with => %r{^http:.+\.(gif|jpg|png)$}i, :message => "must be a URL for a GIF, JPG, or PNG image" protected def validate errors.add(:price, "should be positive") unless price.nil? || price >= 0.01 end end
D:\work\depot\app\views\admin\list.rhtml
<h1>Products Listing </h1> <table cellpadding="5" cellspacing="0"> <% odd_or_even = 0 for product in @products odd_or_even = 1 - odd_or_even %> <tr valign="top" class="ListLine<%= odd_or_even %>"> <td> <img width="60" height="70" src="<%= product.image_url %>"/> </td> <td width="60%"> <span class="ListTitle"><%= h(product.title) %></span><br /> <%= h(truncate(product.description, 80)) %> </td> <td allign="right"> <%= product.date_availbale.strftime("%y-%m-%d") %><br /> <strong>$<%= sprintf("%0.2f", product.price) %></strong> </td> <td class="ListActions"> <%= link_to 'Show', :action => 'show', :id => product %><br /> <%= link_to 'Edit', :action => 'edit', :id => product %><br /> <%= link_to 'Destroy', { :action => 'destroy', :id => product }, :confirm => 'Are you sure?', :method => :post %> </td> <tr> <% end %> </table> <%= if @product_pages.current.previous link_to ('Previous page', { :page => @product_pages.current.previous }) end %> <%= if @product_pages.current.next link_to ('Next page', { :page => @product_pages.current.next }) end %> <br /> <%= link_to 'New product', :action => 'new' %>
修改样式文件
D:\work\depot\public\stylesheets\scaffold.css
.ListTitle { color: #244; font-weight: bold; font-size: larger; } .ListActions { font-size: x-small; text-align: right; padding-left: lem; } .ListLine0 { background: #e0f8f8; } .ListLine1 { background: #f8b0f8; }
新增货品的时候输入的图片地址
http://localhost:3000/images/svn.JPG
http://localhost:3000/images/utc.jpg
http://localhost:3000/images/auto.jpg
第七章 任务B 分类显示
ruby script/generate controller Store index
D:\work\depot\app\controllers\store_controller.rb
class StoreController < ApplicationController def index @products = Product.salable_items end end
D:\work\depot\app\models\product.rb
class Product < ActiveRecord::Base validates_presence_of :title, :description, :image_url validates_numericality_of :price validates_uniqueness_of :title validates_format_of :image_url, :with => %r{^http:.+\.(gif|jpg|png)$}i, :message => "must be a URL for a GIF, JPG, or PNG image" protected def validate errors.add(:price, "should be positive") unless price.nil? || price >= 0.01 end def self.salable_items find(:all, :conditions => "date_available <= now()", :order => "date_available desc") end end
D:\work\depot\app\views\store\index.rhtml
<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>
D:\work\depot\app\views\layouts\store.rhtml
<html> <head> <title>Pragprog Books Online Store</title> <%= stylesheet_link_tag "depot", :media => "all" %> </head> <body> <div id="banner"> <img src="/images/logo.png" /> <%= @page_title || "Pragmatic Bookshelf" %> </div> <div id="columns"> <div id="side"> <a href="http://www....">Home</a><br /> <a href="http://www..../faq">Questions</a><br /> <a href="http://www..../news">News</a><br /> <a href="http://www..../contact">Contact</a><br /> </div> <div id="main"> <%= @content_for_layout %> </div> </div> </body> </html>
D:\work\depot\app\views\store\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 class="separator"> </div> <% end %> <%= link_to "Show my cart", :action => "display_cart" %>
D:\work\depot\public\stylesheets\depot.css
/* Global styles */ /* START:notice */ #notice { border: 2px solid red; padding: 1em; margin-bottom: 2em; background-color: #f0f0f0; font: bold smaller sans-serif; } /* END:notice */ /* Styles for admin/list */ #product-list .list-title { color: #244; font-weight: bold; font-size: larger; } #product-list .list-image { width: 60px; height: 70px; } #product-list .list-actions { font-size: x-small; text-align: right; padding-left: 1em; } #product-list .list-line-even { background: #e0f8f8; } #product-list .list-line-odd { background: #f8b0f8; } /* Styles for main page */ #banner { background: #9c9; padding-top: 10px; padding-bottom: 10px; border-bottom: 2px solid; font: small-caps 40px/40px "Times New Roman", serif; color: #282; text-align: center; } #banner img { float: left; } #columns { background: #141; } #main { margin-left: 15em; padding-top: 4ex; padding-left: 2em; background: white; } #side { float: left; padding-top: 1em; padding-left: 1em; padding-bottom: 1em; width: 14em; background: #141; } #side a { color: #bfb; font-size: small; } h1 { font: 150% sans-serif; color: #226; border-bottom: 3px dotted #77d; } /* And entry in the store catalog */ #store .entry { border-bottom: 1px dotted #77d; } #store .title { font-size: 120%; font-family: sans-serif; } #store .entry img { width: 75px; float: left; } #store .entry h3 { margin-bottom: 2px; color: #227; } #store .entry p { margin-top: 0px; margin-bottom: 0.8em; } #store .entry .price-line { } #store .entry .add-to-cart { position: relative; } #store .entry .price { color: #44a; font-weight: bold; margin-right: 2em; } /* START:inline */ #store .entry form, #store .entry form div { display: inline; } /* END:inline */ /* START:cart */ /* Styles for the cart in the main page and the sidebar */ .cart-title { font: 120% bold; } .item-price, .total-line { text-align: right; } .total-line .total-cell { font-weight: bold; border-top: 1px solid #595; } /* Styles for the cart in the sidebar */ #cart, #cart table { font-size: smaller; color: white; } #cart table { border-top: 1px dotted #595; border-bottom: 1px dotted #595; margin-bottom: 10px; } /* END:cart */ /* Styles for order form */ .depot-form fieldset { background: #efe; } .depot-form legend { color: #dfd; background: #141; font-family: sans-serif; padding: 0.2em 1em; } .depot-form label { width: 5em; float: left; text-align: right; margin-right: 0.5em; display: block; } .depot-form .submit { margin-left: 5.5em; } /* The error box */ .fieldWithErrors { padding: 2px; background-color: red; display: table; } #errorExplanation { width: 400px; border: 2px solid red; padding: 7px; padding-bottom: 12px; margin-bottom: 20px; background-color: #f0f0f0; } #errorExplanation h2 { text-align: left; font-weight: bold; padding: 5px 5px 5px 15px; font-size: 12px; margin: -7px; background-color: #c00; color: #fff; } #errorExplanation p { color: #333; margin-bottom: 0; padding: 5px; } #errorExplanation ul li { font-size: 12px; list-style: square; }
第八章 任务C: 创建购物车
D:\work\depot\app\controllers\store_controller.rb
class StoreController < ApplicationController def index @products = Product.salable_items end private def find_cart session[:cart] ||= Cart.new end end
drop table if exists line_items; create table line_items ( id int not null auto_increment, product_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), primary key (id) );
D:\work\depot\db\product_data.sql
lock tables products write; insert into products( title, description, image_url, price, date_available ) values( 'Pragmatic Project Automation', 'A really great read!', 'http://localhost:3000/images/svn.JPG', '29.95', '2007-12-25 05:00:00' ); insert into products( title, description, image_url, price, date_available ) values( 'Pragmatic Version Control', 'A really contrlooed read!', 'http://localhost:3000/images/utc.jpg', '29.95', '2007-12-01 05:00:00'); insert into products( title, description, image_url, price, date_available ) values( 'Pragmatic Version Control2', 'A really contrlooed read!', 'http://localhost:3000/images/auto.jpg', '29.95', '2007-12-01 05:00:00'); unlock tables;
D:\work\depot>mysql -u root depot_development <db/product_data.sql (导入数据)
下面说明在mysql中 exit 和 quit 命令都可以退出 mysql
D:\work\depot>mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 41 to server version: 5.0.27-community-nt
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> use depot_development
Database changed
mysql> delete from products;
Query OK, 3 rows affected (0.05 sec)
mysql> exit
Bye
D:\work\depot>mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 42 to server version: 5.0.27-community-nt
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> quit
Bye
D:\work\depot>
D:\work\depot>ruby script/generate model LineItem
D:\work\depot\app\models\line_item.rb
class LineItem < ActiveRecord::Base belongs_to :product end
D:\work\depot\app\controllers\store_controller.rb
def add_to_cart product = Product.find(params[:id]) @cart = find_cart @cart.add_product(product) redirect_to(:action => 'display_cart') end
D:\work\depot\app\models\cart.rb
class Cart attr_reader :items attr_reader :total_price def initialize @items = [] @total_price = 0.0 end def add_product(product) @items << LineItem.for_product(product) @total_price += product.price end end
D:\work\depot\app\models\line_item.rb
class LineItem < ActiveRecord::Base belongs_to :product def self.for_product(product) item = self.new item.quantity = 1 item.product = product item.unit_price = product.price item end end
D:\work\depot\app\controllers\store_controller.rb
def display_cart @cart = find_cart @items = @cart.items end
D:\work\depot\app\views\store\display_cart.rhtml
<h1>Display Cart</h1> <p> Your cart contains <%= @items.size %> items. </p>
D:\work\depot\app\controllers\application.rb
# Filters added to this controller apply to all controllers in the application. # Likewise, all the methods added will be available for all controllers. class ApplicationController < ActionController::Base model :cart model :line_item # Pick a unique cookie name to distinguish our session data from others' session :session_key => '_depot_session_id' end
D:\work\depot\app\views\store\display_cart.rhtml
<h1>Display Cart</h1> <table> <% for item in @items product = item.product -%> <tr> <td><%= item.quantity %></td> <td><%= h(product.title) %></td> <td align="right"><%= item.unit_price %></td> <td aling="right"><%= item.unit_price * item.quantity %></td> </tr> <% end -%> <table>
D:\work\depot\app\models\cart.rb
class Cart attr_reader :items attr_reader :total_price def initialize @items = [] @total_price = 0.0 end def add_product(product) item = @items.find {|i| i.product_id == product.id} if item item.quantity += 1 else item = LineItem.for_product(product) @items << item end @total_price += product.price end end
美化购物车
D:\work\depot\app\views\store\display_cart.rhtml
<div id="cartmenu"> <u1> <li><%= link_to 'Continue shopping', :action => "index" %></li> <li><%= link_to 'Empty car', :action => "empty_cart" %></li> <li><%= link_to 'Checkout', :action => "checkout" %></li> </u1> </div> <table cellpadding="10" cellspacing="0"> <tr class="carttitle"> <td rowspan="2">Qty</td> <td rowspan="2">Description</td> <td colspan="2">Price</td> </tr> <tr class="carttitle"> <td>Each</td> <td>Total</td> </tr> <% for item in @items product = item.product -%> <tr> <td><%= item.quantity %></td> <td><%= h(product.title) %></td> <td align="right"><%= item.unit_price %></td> <td align="right"><%=item.unit_price * item.quantity %></td> </tr> <% end %> <tr> <td colspan="3" align="right"><strong>Total:</strong></td> <td id="totalcell"><%= @cart.total_price %></td> </tr> </table>
处理错误
D:\work\depot\app\controllers\store_controller.rb
def add_to_cart product = Product.find(params[:id]) @cart = find_cart @cart.add_product(product) redirect_to(:action => 'display_cart') rescue logger.error("Attempt to access invalid product #{params[:id]}") flash[:notice] = 'Invalid product' redirect_to(:action => 'index') end
D:\work\depot\log\development.log
D:\work\depot\app\views\layouts\store.rhtml
<html> <head> <title>Pragprog Books Online Store</title> <%= stylesheet_link_tag "depot", :media => "all" %> </head> <body> <div id="banner"> <img src="/images/logo.png" /> <%= @page_title || "Pragmatic Bookshelf" %> </div> <div id="columns"> <div id="side"> <a href="http://www....">Home</a><br /> <a href="http://www..../faq">Questions</a><br /> <a href="http://www..../news">News</a><br /> <a href="http://www..../contact">Contact</a><br /> </div> <div id="main"> <% if @flash[:notice] -%> <div id="notice"><%= @flash[:notice] %></div> <% end -%> <%= @content_for_layout %> </div> </div> </body> </html>
D:\work\depot\app\controllers\store_controller.rb
class StoreController < ApplicationController def index @products = Product.salable_items end def add_to_cart product = Product.find(params[:id]) @cart = find_cart @cart.add_product(product) redirect_to(:action => 'display_cart') rescue logger.error("Attempt to access invalid product #{params[:id]}") flash[:notice] = 'Invalid product' redirect_to(:action => 'index') end def display_cart @cart = find_cart @items = @cart.items if @items.empty? flash[:notice] = "Your cart is currently empty" redirect_to(:action => 'index') end end private def find_cart session[:cart] ||= Cart.new end end
D:\work\depot\app\views\store\display_cart.rhtml
<% @page_title = "Your Pragmatic Cart" -%> <div id="cartmenu"> <u1> <li><%= link_to 'Continue shopping', :action => "index" %></li> <li><%= link_to 'Empty car', :action => "empty_cart" %></li> <li><%= link_to 'Checkout', :action => "checkout" %></li> </u1> </div> <table cellpadding="10" cellspacing="0"> <tr class="carttitle"> <td rowspan="2">Qty</td> <td rowspan="2">Description</td> <td colspan="2">Price</td> </tr> <tr class="carttitle"> <td>Each</td> <td>Total</td> </tr> <% for item in @items product = item.product -%> <tr> <td><%= item.quantity %></td> <td><%= h(product.title) %></td> <td align="right"><%= item.unit_price %></td> <td align="right"><%=item.unit_price * item.quantity %></td> </tr> <% end %> <tr> <td colspan="3" align="right"><strong>Total:</strong></td> <td id="totalcell"><%= @cart.total_price %></td> </tr> </table>
完成购物车
D:\work\depot\app\controllers\store_controller.rb
def empty_cart @cart = find_cart @cart.empty! flash[:notice] = 'Your cart is now empty' redirect_to(:action => 'index') end
D:\work\depot\app\models\cart.rb
def empty! @items = [] @total_price = 0.0 end
D:\work\depot\app\controllers\store_controller.rb
class StoreController < ApplicationController def index @products = Product.salable_items end def add_to_cart product = Product.find(params[:id]) @cart = find_cart @cart.add_product(product) redirect_to(:action => 'display_cart') rescue logger.error("Attempt to access invalid product #{params[:id]}") redirect_to_index(:action => 'Invalid product') end def empty_cart @cart = find_cart @cart.empty! redirect_to_index(:action => 'Your cart is now empty') end def display_cart @cart = find_cart @items = @cart.items if @items.empty? redirect_to_index('Your cart is currently empty') end end private def find_cart session[:cart] ||= Cart.new end def redirect_to_index(msg = nil) flash[:notice] = msg if msg redirect_to(:action => 'index') end end
D:\work\depot\app\models\cart.rb
class Cart attr_reader :items attr_reader :total_price def initialize empty! end def empty! @items = [] @total_price = 0.0 end def add_product(product) item = @items.find {|i| i.product_id == product.id} if item item.quantity += 1 else item = LineItem.for_product(product) @items << item end @total_price += product.price end end
辅助方法
D:\work\depot\app\helpers\application_helper.rb
# Methods added to this helper will be available to all templates in the application. module ApplicationHelper def fmt_dollars(amt) sprintf("$%0.2f", amt) end end
D:\work\depot\app\views\store\display_cart.rhtml
<% @page_title = "Your Pragmatic Cart" -%> <div id="cartmenu"> <u1> <li><%= link_to 'Continue shopping', :action => "index" %></li> <li><%= link_to 'Empty car', :action => "empty_cart" %></li> <li><%= link_to 'Checkout', :action => "checkout" %></li> </u1> </div> <table cellpadding="10" cellspacing="0"> <tr class="carttitle"> <td rowspan="2">Qty</td> <td rowspan="2">Description</td> <td colspan="2">Price</td> </tr> <tr class="carttitle"> <td>Each</td> <td>Total</td> </tr> <% for item in @items product = item.product -%> <tr> <td><%= item.quantity %></td> <td><%= h(product.title) %></td> <td align="right"><%= fmt_dollars(item.unit_price) %></td> <td align="right"><%= fmt_dollars(item.unit_price * item.quantity) %></td> </tr> <% end %> <tr> <td colspan="3" align="right"><strong>Total:</strong></td> <td id="totalcell"><%= fmt_dollars(@cart.total_price) %></td> </tr> </table>
D:\work\depot\app\views\store\index.rhtml
<% for product in @products %> <div class="catalogentry"> <img src="<%= product.image_url %>"/> <h3><%=h product.title %></h3> <%= product.description %> <span class="catalogprice"><%= fmt_dollars(product.price) %></span> <%= link_to 'Add to Cart', {:action => 'add_to_cart', :id => product }, :class => 'addtocart' %><br /> <div class="separator"> </div> <% end %> <%= link_to "Show my cart", :action => "display_cart" %>
第九章 任务D: 结账
D:\work\depot\db\create.sql
drop table if exists line_items; drop table if exists orders; drop table if exists products; create table products ( id int not null auto_increment, title varchar(100) not null, description text not null, image_url varchar(200) not null, price decimal(10,2) not null, date_available datetime not null, primary key(id) ); 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) ); 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) );
D:\work\depot\app\models\order.rb
class Order < ActiveRecord::Base has_many :line_items end
D:\work\depot\app\models\line_item.rb
class LineItem < ActiveRecord::Base belongs_to :product belongs_to :order def self.for_product(product) item = self.new item.quantity = 1 item.product = product item.unit_price = product.price item end end
D:\work\depot\app\controllers\store_controller.rb
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
D:\work\depot\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 %>
D:\work\depot\app\models\order.rb
class Order < ActiveRecord::Base has_many :line_items PAYMENT_TYPES = [ [ "Check", "check"], [ "Credit Card", "cc"], [ "Purchas Order", "po"] ].freeze # freeze to make this array constant end
D:\work\depot\app\controllers\store_controller.rb
class StoreController < ApplicationController def index @products = Product.salable_items end def add_to_cart product = Product.find(params[:id]) @cart = find_cart @cart.add_product(product) redirect_to(:action => 'display_cart') rescue logger.error("Attempt to access invalid product #{params[:id]}") redirect_to_index(:action => 'Invalid product') end def empty_cart @cart = find_cart @cart.empty! redirect_to_index(:action => 'Your cart is now empty') end def display_cart @cart = find_cart @items = @cart.items if @items.empty? redirect_to_index('Your cart is currently empty') end end 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 def save_order @cart = find_cart @order = Order.new(params[:order]) @order.line_items << @cart.items if @order.save @cart.empty! redirect_to_index('Thank you for your order.') else render(:action => 'checkout') end end private def find_cart session[:cart] ||= Cart.new end def redirect_to_index(msg = nil) flash[:notice] = msg if msg redirect_to(:action => 'index') end end
D:\work\depot\app\models\order.rb
class Order < ActiveRecord::Base has_many :line_items PAYMENT_TYPES = [ [ "Check", "check"], [ "Credit Card", "cc"], [ "Purchas Order", "po"] ].freeze # freeze to make this array constant validates_presence_of :name, :email, :address, :pay_type end
D:\work\depot\app\views\layouts\store.rhtml
<html> <head> <title>Pragprog Books Online Store</title> <%= stylesheet_link_tag "scaffold", "depot", :media => "all" %> </head> <body> <div id="banner"> <img src="/images/logo.png" /> <%= @page_title || "Pragmatic Bookshelf" %> </div> <div id="columns"> <div id="side"> <a href="http://www....">Home</a><br /> <a href="http://www..../faq">Questions</a><br /> <a href="http://www..../news">News</a><br /> <a href="http://www..../contact">Contact</a><br /> </div> <div id="main"> <% if @flash[:notice] -%> <div id="notice"><%= @flash[:notice] %></div> <% end -%> <%= @content_for_layout %> </div> </div> </body> </html>
mysql> select * from orders;
+----+------+---------------+----------------+----------+
| id | name | email | address | pay_type |
+----+------+---------------+----------------+----------+
| 3 | aaaa | bbbb@aaaa.com | aaaa bbbb cccc | cc |
+----+------+---------------+----------------+----------+
1 row in set (0.00 sec)
mysql> select * from line_items;
+----+------------+----------+----------+------------+
| id | product_id | order_id | quantity | unit_price |
+----+------------+----------+----------+------------+
| 1 | 1 | 3 | 1 | 29.95 |
| 2 | 2 | 3 | 1 | 29.95 |
| 3 | 3 | 3 | 1 | 29.95 |
+----+------------+----------+----------+------------+
3 rows in set (0.00 sec)
迭代D2: 在付账页面显示购物车内容
D:\work\depot\app\views\store\checkout.rhtml
<% @page_title = "Checkout" -%> <%= error_messages_for("order") %> <%= render_component(:acton => "display_cart") %> <%= 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 %>
D:\work\depot\app\views\store\checkout.rhtml
<% @page_title = "Checkout" -%> <%= error_messages_for("order") %> <%= render_component(:acton => "display_cart", :params => { :context => :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 %>
D:\work\depot\app\controllers\store_controller.rb
修改如下方法:
def display_cart @cart = find_cart @items = @cart.items if @items.empty? redirect_to_index('Your cart is currently empty') end if params[:context] == :checkout render(:layout => false ) end end
D:\work\depot\app\views\store\display_cart.rhtml
<% @page_title = "Your Pragmatic Cart" -%> <div id="cartmenu"> <u1> <li><%= link_to 'Continue shopping', :action => "index" %></li> <% unless params[:context] == :checkout -%> <li><%= link_to 'Empty car', :action => "empty_cart" %></li> <li><%= link_to 'Checkout', :action => "checkout" %></li> <% end -%> </u1> </div> <table cellpadding="10" cellspacing="0"> <tr class="carttitle"> <td rowspan="2">Qty</td> <td rowspan="2">Description</td> <td colspan="2">Price</td> </tr> <tr class="carttitle"> <td>Each</td> <td>Total</td> </tr> <% for item in @items product = item.product -%> <tr> <td><%= item.quantity %></td> <td><%= h(product.title) %></td> <td align="right"><%= fmt_dollars(item.unit_price) %></td> <td align="right"><%= fmt_dollars(item.unit_price * item.quantity) %></td> </tr> <% end %> <tr> <td colspan="3" align="right"><strong>Total:</strong></td> <td id="totalcell"><%= fmt_dollars(@cart.total_price) %></td> </tr> </table>
D:\work\depot\app\views\store\checkout.rhtml
<% @page_title = "Checkout" -%> <%= error_messages_for("order") %> <%= render_component(:acton => "display_cart", :params => { :context => :checkout }) %> <h3>Please enter your details below</h3> <%= 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 %>
发表评论
-
ruby on rails demo
2008-04-06 15:27 12351 install ruby 2 install rails ... -
学习ruby on rails 笔记(第一版)depot源代码
2008-02-20 12:21 3453完整的Depot应用源代码 Source Code 参考 《 ... -
rails demo
2008-02-13 22:38 1633d:\>mkdir work d:\>cd wo ... -
rails 启动两个 script/server 报的错误
2008-02-13 21:34 2281E:\work\Depot>ruby script/se ... -
rails 的版本问题
2008-02-12 21:17 1083D:\work\depot>ruby script/se ... -
用 rails 新建一个应用程序
2007-12-23 00:12 1551D:\>cd work D:\work>dir ... -
mysql 的安装
2007-12-22 23:38 997mysql 的中文官方网站 http://www.mysql. ... -
ruby 的安装
2007-12-22 23:25 1119网址 进入ruby的官方网站 http://www.rub ... -
ruby on rails 的安装
2007-12-22 23:19 2398第一种方法: 采用Curt Hibbs的 InstantRai ... -
ruby on rails 下载
2007-10-09 09:10 2891ruby on rails 下载地址: http://ruby ...
相关推荐
第一章“Ruby on Rails概述”,介绍了Ruby on Rails的基本概念和开发环境的搭建方法。通过这一章的学习,读者将对Rails框架有一个整体的认识,并了解如何搭建开发环境以及设计用户界面(UI)。 第二章“Rails中的...
陈刚撰写的《Ruby on Rails心得_V0.1》是一份非常宝贵的资料,旨在记录作者在学习Ruby on Rails过程中的所见所得,包括读书笔记、心得体会、自创教程及一些常见问题的解决方案。作者通过写作这种方式不仅加深了对...
本资料包“ruby-on-the-way”显然是一份用于学习Ruby和Rails的资源集合,旨在帮助初学者掌握这两项技术。 首先,让我们深入了解Ruby语言的关键特性: 1. 动态类型:Ruby不像Java或C++那样需要提前声明变量的类型,...
"ruby笔记2ruby笔记2ruby笔记2"可能是指一系列关于Ruby学习的笔记,这些笔记可能涵盖了Ruby的基础概念、核心特性以及进阶话题。在Ruby的学习过程中,理解和掌握以下几个关键知识点至关重要: 1. **面向对象编程...
其次,"Ruby初级教程(Ruby用户指南).chm"是针对初学者的教程,它详细解释了如何开始使用Ruby,包括安装Ruby环境、编写第一个程序、变量、控制结构等基础知识。对于刚接触Ruby的人来说,这是个很好的起点。 "Ruby...
Ruby是Rails的基础,因此在Windows XP上安装Ruby是第一步。你可以访问Ruby官方网站(ruby-lang.org)下载适合Windows的Ruby安装包。确保下载与你的系统兼容的版本,通常是x86架构。安装过程中,记得勾选添加Ruby到...
标题 "我的ror的第一天" 暗示了这是一个关于Ruby on Rails (RoR) 开发初体验的分享,其中可能涵盖了作者初次接触RoR时的学习过程、遇到的问题以及解决方法。Rails是Ruby的一个Web开发框架,它以MVC(模型-视图-控制...
尽管如此,我们可以从 "railstutorial4th-1.0.0.pdf" 这个文件名中推测,这可能是 Michael Hartl 的《Ruby on Rails 教程》第四版的早期版本。这本书是学习 Rails 的经典参考资料,涵盖了从基础到高级的许多主题。 ...
【描述】中的"#我的第一次ROR学习"表明这是一个初学者的学习笔记,记录了作者初次接触并尝试理解Rails的体验。提到"ando"可能是指作者在学习过程中参考了一位名叫Ando的人的教程或者资源。"ror教程"则可能指的是...
总结来说,"Lin-Ether.github.io" 是一个使用 Ruby on Rails 或相关静态站点生成器构建的个人博客项目,作者通过它分享学习笔记。博客尚未完成,未来可能有更多内容更新。对于对 Ruby 或 web 开发感兴趣的人来说,这...
这个目录可能包含了一系列关于Ruby学习的笔记、代码示例、练习项目或其他资源。 详细知识点: 1. **面向对象编程**:Ruby是一种纯面向对象的语言,所有数据都是对象,每一个操作都可以看作是对对象的方法调用。 2...
Mastodon 的核心是 Ruby on Rails,这是一个流行的Web开发框架,基于Ruby编程语言。Rails 提供了一套完整的工具链,用于快速构建数据驱动的Web应用程序。它的MVC(模型-视图-控制器)架构模式使得开发者能够清晰地...
3. **Web框架应用**:为了提高开发效率,Web开发者通常使用框架,如Java的Spring、Python的Django或Flask、Ruby on Rails等。这些框架提供了预设的结构和功能,如路由、模板引擎、ORM(对象关系映射)。学习框架能...
话说我当年接触Spring的时候着实兴奋了好一阵,IoC的概念当初第一次听说,感觉有种开天眼的感觉。记得当时的web框架和如今的前端框架的局面差不多啊,都是群雄纷争。但一晃好多年没写过后端,代码这东西最怕手生,...
话说我当年接触Spring的时候着实兴奋了好一阵,IoC的概念当初第一次听说,感觉有种开天眼的感觉。记得当时的web框架和如今的前端框架的局面差不多啊,都是群雄纷争。但一晃好多年没写过后端,代码这东西最怕手生,...
Ruby on Rails(简称Rails)是一个流行的Web应用框架,它遵循MVC(模型-视图-控制器)架构模式,大大简化了Web开发。 在压缩包"odinproject-master"中,你可能找到了以下类型的文件: - **练习和项目代码**:每个...
16. **Ruby on Rails**:基于Ruby语言的Web开发框架,以其"约定优于配置"的理念著称。 17. **Sublime Text 2**:广受欢迎的代码编辑器,拥有丰富的插件和快捷键,提高开发效率。 18. **SourceTree**:Git的图形化...