上一节:Ruby on Rails实战–创建一个网上商店C小试Ajax
本节完成收银台功能. 为页面新增一个结账按钮,用户挑选商品后点击结账按钮时出现一个用户资料表单,用户填交后,系统将商品信息和用户信息保存到数据库中.
创建order model
depot> ruby script/generate model order
修改depot/db/migrate/005_create_orders.rb 内容为:
class CreateOrders < ActiveRecord::Migration
def self.up
create_table :orders do |t|
t.column :name, :string
t.column :address, :text
t.column :email, :string
t.column :pay_type, :string, :limit => 10
end
end
def self.down
drop_table :orders
end
end
创建line_item model,
depot>ruby script/generate model line_item
修改depot/db/migrate/006_create_line_items.rb文件内容为:
class CreateLineItems < ActiveRecord::Migration
def self.up
create_table :line_items do |t|
t.column :product_id, :integer, :null => false
t.column :order_id, :integer, :null => false
t.column :quantity, :integer, :null => false
t.column :total_price, :integer, :null => false
end
#创建两个foreign key
execute "alter table line_items
add constraint fk_line_item_products
foreign key (product_id) references products(id)"
execute "alter table line_items
add constraint fk_line_item_orders
foreign key (order_id) references orders(id)"
end
def self.down
drop_table :line_items
end
end
向数据库应用
depot> rake db:migrate
关联model:
在depot/app/models/order.rb和
depot/app/models/product.rb两文件者加入:
has_many :line_items
声明这两个model下有多个line_items
在depot/app/models/line_item.rb文件中加入:
belongs_to :order
belongs_to :product
声明这个model从属于order和product
*if a table has foreign keys, the corresponding model should have a belongs_to for each.
添加结账按钮:
在depot/app/views/store/_cart.rhtml文件:
<%= button_to "Empty cart", :action => :empty_cart %>
行上方加入:
<%= button_to "Checkout", :action => :checkout %>
checkout action
在depot/app/controllers/store_controller.rb文件中定义checkout action 和save_order action:
def checkout
@cart = find_cart
if @cart.items.empty?
#判断篮中是否为空
redirect_to_index("Your cart is empty")
else
@order = Order.new
end
end
def save_order
@cart = find_cart
@order = Order.new(params[:order])
@order.add_line_items_from_cart(@cart)
if @order.save #保存数据
session[:cart] = nil #清空购物篮
redirect_to_index("Thank you for your order")
else
render :action => :checkout
end
end
相应 checkout 的view文件depot/app/views/store/checkout.rhtml内容为:
<div class="depot-form">
<%= error_messages_for ‘order’ %>
<fieldset>
<legend>Please Enter Your Details</legend>
<% form_for :order, :url => { :action => :save_order } do |form| %>
<p>
<label for="order_name">Name:</label>
<%= form.text_field :name, :size => 40 %>
</p>
<p>
<label for="order_address">Address:</label>
<%= form.text_area :address, :rows => 3, :cols => 40 %>
</p>
<p>
<label for="order_email">E-Mail:</label>
<%= form.text_field :email, :size => 40 %>
</p>
<p>
<label for="order_pay_type">Pay with:</label>
<%=
form.select :pay_type,
Order::PAYMENT_TYPES,
#这个下拉列表内容另定义
:prompt => "Select a payment method"
%>
</p>
<%= submit_tag "Place Order", :class => "submit" %>
<% end %>
</fieldset>
</div>
上面蓝色的代码用来组建form.
在depot/app/models/order.rb文件中定义上面下拉列表的PAYMENT_TYPES内容:
PAYMENT_TYPES = [
# 显示文字 数据库内容
[ "Check", "check" ],
["Credit card", "cc" ],
["Purchase order", "po" ]
]
#校验用户名,地址,信箱地址和支付方式是否为空
validates_presence_of :name, :address, :email, :pay_type
#校验支付方式是否合法(加强安全性)
validates_inclusion_of :pay_type, :in => PAYMENT_TYPES.map {|disp, value| value}
#定义上面用到的add_line_items_from_cart()
def add_line_items_from_cart(cart)
cart.items.each do |item|
li = LineItem.from_cart_item(item)
line_items << li
end
end
修改depot/app/models/line_item.rb文件内容为:
class LineItem < ActiveRecord::Base
belongs_to :order
belongs_to :product
def self.from_cart_item(cart_item)
li = self.new
li.product = cart_item.product
li.quantity = cart_item.quantity
li.total_price = cart_item.price
li
end
end
在depot/app/views/store/add_to_cart.rjs文件中加入:
page.select(‘div#notice’).each { |div| div.hide }
搜索页面中id=notice的div,如有找到,将div隐藏.
在用户结账后继续购物时隐藏结账成功提示语.
本节结束
下一节:Ruby on Rails实战–创建一个网上商店E用户管理模块
转载请注明: 转自船长日志, 本文链接地址: http://www.cslog.cn/Content/ruby_on_rails_eshop_checkout/