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前台

此條目發表在 Ruby on Rails 分類目錄。將固定鏈接加入收藏夾。

Ruby on Rails實戰–創建一個網上商店a》有 1 條評論

  1. brant 說:

    請問是否貽誤了 配置數據庫的步驟?

發表評論