Ruby on Rails实战–创建一个网上商店B前台

上一节: Ruby on Rails实战–创建一个网上商店a
本节创建商店的前台模块, 也就是客户看到的页面.

1.创建前台Controller Store:depot> ruby script/generate controller store index
最后的index创建一个index Action,用作默认action

2.创建一个session,用来保存购物篮数据
depot> rake db:sessions:create
然后
depot> rake db:migrate
(users of Rails applications must have cookies enabled in their browsers.???)
在config/environment.rb中将
config.action_controller.session_store = :active_record_store
语句前的注解符#去除,启动数据库保存session功能
*使用depot> rake db:sessions:clear可以清空当前session内容

3.创建前台的Store的Controller
修改depot/app/controllers/store_controller.rb文件为
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
class StoreController < ApplicationController
  def index
    @products = Product.find_products_for_sale
  end
  #find_products_for_sale将在model里面定义,见下文
  #下面是购物篮添加程序
  def add_to_cart
    begin
      @product = Product.find(params[:id])
    rescue
      logger.error("Attempt to access invalid product #{params[:id]}")
      redirect_to_index("Invalid product")
    else
      @cart = find_cart
      @cart.add_product(@product)
    end
  end
  #上面的begin…rescue…else…end用来处理错误
  #当begin出错,即找不到当前ID的商品时进行rescue处理,以防止入侵或意外出错
  #上面的logger.eeror用来记录错误log,对应log目录里的development.log文件
  # @product = Product.find(params[:id])可以接 add_to_cart/1 样式传来的request.
  #上面的redirect_to_index见下面代码
  #上面的find_cart见下面代码
  #add_product()代码见下面.

  #下面是购物篮清空程序
  def  empty_cart
    session[:cart] = nil
    redirect_to_index("Your cart is currently empty")
  end

  private #开始定义局部代码

#一个高压缩处理了的错误信息显示代码
  def redirect_to_index(msg)
    flash[:notice] = msg #用来显示出错信息
    redirect_to :action => :index
  end
#flash[:notice] = msg #用来显示flash信息
#redirect_to :action => :index 可用来转移页面.

#使用session来保存购物篮数据
  def find_cart
    session[:cart] ||= Cart.new
  end
end
#上面的||=语句用来创建检查session,如果存在则调出数据,如果不存在生成新session
#!!!好符号化的语言啊!!!日本人不太懂英语吧.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

4.创建model:
修改depot/app/models/product.rb文件为:
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
class Product < ActiveRecord::Base
  def self.find_products_for_sale
    find(:all, :order => "title")
  end
 #用 self.前缀,定义class method
  #上面的find(:all, :order => "title")让程序列出所有商品,按标题排序
  #以下为原来的效验代码….
end
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

手动创建一个depot/app/models/cart.rb, 作为购物篮的model,内容如下:
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
class Cart
  include Reloadable #手动创建的model要加入这句,以后服务器才会自动刷新
  #Whenever youcreatea non-database model, youneed toinclude a includeReloadable directive in the source.
  attr_reader :items 
  def initialize #初始化method
    @items = [] # @items = []来赋空集.
  end
  def add_product(product)
    existing_product = @items.find {|item| item.product == product}
    if existing_product #如果篮中已有商品,累加数量
      existing_product.increment_quantity
    else
      @items << CartItem.new(product)
    end
  end
  def total_price
    @items.inject(0) { |sum, item| sum + item.price }
  end
end
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

手动创建一个depot/app/models/cart_item.rb model,用来处理购物篮内的商品,内容如下:
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
class CartItem
  include Reloadable #见上文
  attr_reader :product, :quantity
  def initialize(product)
    @product = product
    @quantity = 1
  end
  def increment_quantity
    @quantity += 1
  end
  def title
    @product.title
  end
  def price
    @product.price * @quantity
  end
end
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

5.创建View:
修改depot/app/views/store/index.rhtml文件为:
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<% for product in @products -%>
 <div class="entry">
  <img src="<%= product.image_url %>"/>
  <h3><%= h(product.title) %></h3>
  <%= product.description %>
  <span class="price"><%= format_price(product.price) %></span>
  <%= button_to "Add to Cart", :action => :add_to_cart, :id => product %>
 </div>
 <br />
<% end %>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
*上面的product.description为使描述带有HTML代码,没有使用h(),带有安全隐患.
*上面的format_price为一个helper,来用格式化整数形的价格.见下文.
*上面的button_to将生成一个按钮,链接到add_to_cart action,用于向购物篮添加商品,它将以post方向向add_to_cart action传送商品ID信息. (post比get好???)
(And a POST request is just the ticket when we want to do something like add an item to a cart.)
*button_to的作用实际上相应于生成如下代码:
<form method="post" action="/store/add_to_cart/1" class="button-to">
<input type="submit" value="Add to Cart" />
</form>

手动建立一个添加商品页面的view depot/app/views/store/add_to_cart.rhtml,文件内容如下:
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<div class="cart-title">Your Cart</div>
<table>
 <% for cart_item in @cart.items %>
  <tr>
   <td><%= cart_item.quantity %> &times;</td>
   <td><%= h(cart_item.title) %></td>
   <td class="item-price"><%= format_price(cart_item.price) %></td>
  </tr>
 <% end %>
 <tr class="total-line">
  <td colspan="2">Total</td>
  <td class="total-cell"><%= format_price(@cart.total_price) %></td>
 </tr>
</table>
<%= button_to "Empty cart", :action => :empty_cart %>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
* &times;生成一个乘号.

6.增加format_price helper
修改depot/app/helpers/store_helper.rb文件为:
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
module StoreHelper
  def format_price(amount)
    dollars, cents = amount.divmod(100)
    sprintf("$%d.%02d", dollars, cents)
  end
end
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
*上面的divmod是一个内置方法. 用它将以分为单位的整数形价格分为元和分两部分.

7.给view添加一个模板
修改:depot/app/views/layouts/store.rhtml文件内容为:
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<html>
 <head>
  <title>Pragprog Books Online Store</title>
  <%= stylesheet_link_tag "depot", :media => "all" %>
 </head>
 <body id="store">
  <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 -%>
    <!–下面的代码显示不同action的子view内容–>
    <%= @content_for_layout %>
    <!–其它的内容为共用模板–>
   </div>
  </div>
 </body>
</html>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
*这个和controller同名的layout文件为view的默认模板.
*<%= @page_title || "Pragmatic Bookshelf" %> ???

到这里用户界面已经基本完成.
调试使用 http://localhost:3000/store/访问

下一节:Ruby on Rails实战–创建一个网上商店C小试Ajax

转载请注明: 转自船长日志, 本文链接地址: http://www.cslog.cn/Content/ruby_on_rails_e_shop_b/

相关日志:

  1. Ruby on Rails项目文件目录结构和环境设置
  2. Ruby on Rails 的Active Record之Acts As List和Acts As Tree
  3. US States List for Ruby on Rails
  4. learning ruby 7, Expressions
  5. Open MDB file on Ubuntu, convert it to CSV, import it to Rails
此条目发表在 Ruby on Rails 分类目录。将固定链接加入收藏夹。

Ruby on Rails实战–创建一个网上商店B前台》有 1 条评论

  1. CDMYNAME 说:

    smart man !
    thank you very much !
    It’s suitable for beginners.

发表评论

电子邮件地址不会被公开。 必填项已被标记为 *

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>