Ruby on Rails实战–创建一个网上商店a

这是一个使用Ruby on Rails创建一个网上商店的实例. 实例来自<Agile Web Development with Rails>第二版 beta. 下面是我整理的笔记. 笔记对实例进行了注解, 记录我的学习路程, 同在学习Ruby on Rails的朋友可作为参考. 如果里面有什么错误,还请留言指正.
按学习日程,我把这个实例分为几段, 分别完成: 网上商店基本构架 Ruby语言入门

这是第一部分, 完成商店的基本构架.

首先要在准备好实例的学习环境, 参考: 在Windows平台上学习Ruby on Rails 的环境准备

1.it’s easier to throw something away if you didn’t spend a long time creating it.
2.使用笔+纸打草图以加快速度.

以下的命令都是在ruby on rails的命令输入窗进行的.
3.项目代号Depot,创建相应项目:work> rails depot
4.创建mysql数据库depot_development:
depot> mysqladmin -u root create depot_development
注意mysql的用户名和密码.
数据库测试:depot> rake db:migrate
不显示错误提示为正常.
rake db:migrate也用来应用数据库的修改, 以后会经常用到.

下面开始创建后台功能

5.创建model product:depot> ruby script/generate model Product
生成的文件名001_create_products.rb中的001为版本号.
修改db/migrate/001_create_products.rb内容为:
—————————————————————————
class CreateProducts < ActiveRecord::Migration
  def self.up
    create_table :products do |t|
      t.column :title, :string
      t.column :description, :text
      t.column :image_url, :string
    end
  end
  def self.down
    drop_table :products
  end
end
—————————————————————————
使用rake命令应用数据库:depot> rake db:migrate
后面的:string是数据类型,常用的数据类型还有:text,integer,time…

7.创建Controller admin:depot> ruby script/generate controller admin
修改depot/app/controllers/admin_controller.rb内容为:
class AdminController < ApplicationController
 scaffold :product
end
scaffold是rails的一个内建model框架.
现在启动服务器(depot> ruby script/server)调试,后台功能已经基本实现.
调试方法请参看: 网上商店基本构架  Ruby语言入门

这是第一部分, 完成商店的基本构架.

首先要在准备好实例的学习环境, 参考: Ruby on Rails入门 –写第一个程序

8.向数据库追加字段price
生成追加文件:depot> ruby script/generate migration add_price
修改文件depot/db/migrate/002_add_price.rb内容为:
—————————————————————————–
class AddPrice < ActiveRecord::Migration
  def self.up
    add_column :products, :price, :integer, :default => 0
  end
  def self.down
    remove_column :products, :price
  end
end
—————————————————————————-
*可以使用:default=>0为price字段设置默认值.
可用参数:
default=>0设定默认值
null=>false设定不能为空
limit => 10
应用数据库改变:depot> rake db:migrate

9.为数据输入增加校验功能
修改depot/app/models/product.rb为:
——————————————————————————-
class Product < ActiveRecord::Base
  validates_presence_of :title, :description, :image_url
  validates_numericality_of :price, :only_integer => true
  protected
  def validate
    errors.add(:price,"should be positive") if price.nil? || price <= 0
  end

  validates_uniqueness_of :title
  validates_format_of :image_url,
  :with => %r{.(gif|jpg|png)$}i,
  :message =>"must be a URL for a GIF, JPG, or PNG image"
end
——————————————————————————-
*其中validates_presence_of指定字段输入不能为空.
*validates_numericality_of指定字段为数字(浮点数)
*  protected
  def validate
    errors.add(:price,"should be positive") if price.nil? || price <= 0
  end

  让price字段不为空,且大于0,否则显示"price should be positive"提示.
  protected参见: 网上商店基本构架  Ruby语言入门

这是第一部分, 完成商店的基本构架.

首先要在准备好实例的学习环境, 参考: Ruby语言入门

validate???
*validates_uniqueness_of指定字段不能有重复内容
*validates_format_of和后面的正则表达式限制图片路径指向指定格式的图片文件.
其它:
  validates_length_of :name, :within => 6..100 指定字段长度取值范围
  validates_length_of :content, :minimum => 10  指定长度最小值
  validates_associated :bliki ????

10.以脚本方式向数据库追加内容
创建新migration: depot> ruby script/generate migration add_test_data
修改depot/db/migrate/003_add_test_data.rb文件内容为:
——————————————————————————————-
class AddTestData < ActiveRecord::Migration
  def self.up
    Product.create(:title =>’Pragmatic Version Control’,
    :description =>
%{<p>This book is a recipe-based approach to using Subversion that will get you up and running quickly–and correctly. All projects need’s a foundational piece of any project’s version control: it infrastructure. Yet half of all project teams in the U.S. don’t use any version control at all. Many others don’t use it well, and end up experiencing time-consuming problems.</p>},
    :image_url =>’/images/svn.jpg’,
    :price => 2850)
    # . . .
  end
  def self.down
    Product.delete_all
  end
end
————————————————————————————————
使用rake db:migrate命令应用到数据库

10.美化商品列表
分离出scaffold代码:depot> ruby script/generate scaffold product admin
scaffold为rails提供的内建动态功能,使用上面的语句将代码分离出来,以便修改.
分离过程需要按两次"y"确认.
depot/app/controllers/admin_controller.rb文件被修改
修改depot/app/views/layouts/admin.rhtml文件,将
<%= stylesheet_link_tag ‘scaffold’ %>
修改为:
<%= stylesheet_link_tag ‘scaffold’, ‘depot’ %>
这会将网站使用的CSS文件由默认的scaffold.css指向depot.css文件.
在public/stylesheets目录下新建depot.css文件,内容为:
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
/*Global styles*/
#notice {
border: 2px solid red;
padding: 1em;
margin-bottom: 2em;
background-color:#f0f0f0;
font: bold smaller sans-serif;
}
/*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;
float: left;
}

/*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;
}
/*Styles for order form*/
.depot-form fieldset {
background:#efe;
}
.depot-form legend {
color:#dfd;
background:#141;
font-style: 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;
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
这个文件包含整站的CSS代码.

修改depot/app/views/admin/list.rhtml文件内容为:
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<div id="product-list">
 <h1>Product Listing</h1>
 <table cellpadding="5" cellspacing="0">
  <% for product in @products %>
   <tr valign="top" class="<%= cycle(‘list-line-odd’, ‘list-line-even’) %>">
    <td>
     <img class="list-image" src="<%= product.image_url %>"/>
    </td>
    <td width="60%">
     <span class="list-title"><%= h(product.title) %></span><br />
     <%= h(truncate(product.description, 80)) %>
    </td>
    <td class="list-actions">
     <%= 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?",
     :post => true
%>
    </td>
   </tr>
  <% end %>
 </table>
</div>
<%= 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’ %>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
系统自动提供@products变量.
手动创建的方法是:
在controller里字义@products = Product.find_products_for_sale
在Product类(models/product.rb)里定义:
class Product < ActiveRecord::Base
  def self.find_products_for_sale
    find(:all, :order => "title")
  end
  #….
 用 self.前缀,定义class method
*h(string) 用来处理html符号.
*class=cycle(‘样式名1′,’样式名2′)是一个helper method,用于在连续的行之间交互不同的样式.
*truncate(‘字串’,长度数值)用来截取字符
*link_to用法 link_to ‘链接标题’, :action => ‘action名’, :id => product
*link_to ’Destroy’后面的:confirm =>"Are you sure?"会为页面加入一个删除确认提示.
* :post => true强制rails使用post方式传输数据,这个方式比get方式更适合用来做"删除数据"链接

使用http://localhost:3000/admin/ 地址访问调试.

本节结束.
下一节:
网上商店基本构架  Ruby语言入门

这是第一部分, 完成商店的基本构架.

首先要在准备好实例的学习环境, 参考: Ruby on Rails实战–创建一个网上商店B前台

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

此条目发表在 Ruby on Rails 分类目录。将固定链接加入收藏夹。

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

  1. brant 说:

    请问是否贻误了 配置数据库的步骤?

发表评论