การสร้าง application E-commerce

บทที่ 1 : สร้างส่วนของการจัดการรายการสินค้า สำหรับ admin (Product maintenance)

สร้างหน้าแรกของ site ที่จะแสดงข้อมูลของสินค้า โดยมีการทำงานดังนี้

  • สร้างสินค้าใหม่
  • แก้ไขข้อมูลของสินค้าเดิม
  • ลบสินค้าทีละอัน

สิ่งที่จะต้องเตรียมในขั้นพื้นฐาน

  • สร้าง database และ table ที่จะเก็บข้อมูลสินค้า
  • config Rails แอพลิเคชั่นให้ชี้ไปที่ database นั้น
  • มี Rails ที่จะนำมาใช้เป็น version เริ่มต้นสำหรับการพัฒนาครั้งนี้

Flow การสร้างหน้าจอ เพื่อจัดการรายการสินค้า

manageProduct4.png

ขั้นตอนการสร้างหน้าจอ เพื่อจัดการรายการสินค้า

1. สร้าง Rails Application ชื่อ ecommerce
2. Run Instant Rails เพื่อทดสอบ Application ที่สร้างขึ้น
3. สร้างฐานข้อมูล ชื่ิอ ecommerce_development
  3.1 Config appplication ให้ติดต่อกับฐานข้อมูล
4. สร้างหน้าจอ จัดการสินค้าด้วย Rails Scaffold Framework
5. ปรับปรุงหน้าจอ
  5.1 แก้ไข views ชื่อ list.rhtml
  5.2 แก้ไข CSS ชื่อ scaffold.css

สร้าง Rails Application

Run Instant Rails

BU1.png

BU2.png

BU3.png

BU4.png

BU5.png


Tool ในการเขียน Ruby ใช้ Radrails

เปิด radrails program และสร้าง application ใหม่ ตามขั้นตอน ดังรูป

ecom_radrails1.jpg

ecom_radrails2.jpg

สร้าง application ชื่อ ecommerce

ecom_radrails3.jpg

จะเห็นไดเรกทอรีเกิดขึ้นชื่อ ecommerce และเห็นไฟล์เกิดขึ้นเป็นจำนวนมาก ซึ่งไฟล์เหล่านี้เองจะเป็นไฟล์ตั้งตั้นสำหรับการเขียน Ruby On Rails

ecom_directory.jpg


การ Run Instant Rails

เป็นการ start การทำงานของ web application ที่เราสร้างขึ้น โดยเราจะเลือกที่ “ecommerce” และ run WEBrick หลังจากนั้นจะมี popup command ขึ้นมา เพื่อแสดงการ run WEBrick โดยในที่นี้จะใช้ port 3000 ในการทำงาน ดังนั้นให้จำไว้ว่าเวลาเราเรียก web application ทาง URL ต้องมีการระบุ port ต่อท้ายเสมอ

ecom_webrick.jpg

ecom_webrick3.jpg

สร้าง Database สำหรับส่วนของ admin

ในที่นี้เราจะใช้ Database MySQL? ใช้ชื่อว่า “ecommerce_development” ดังภาพ

ecom_create_db.jpg

สร้างตารางชื่อ 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` DATE NOT NULL ,
PRIMARY KEY ( `id` )
);

ดังภาพ

ecom_create_sql.jpg

ecom_create_sql2.jpg

การ Config Rails Application กับ database

แก้ไขไฟล์ database.yml ที่ path ต่อไปนี้ (/ecommerce/config/database.yml) ตรงส่วนของ ชื่อ database,username,password ดังภาพ

ecom_config_app.jpg

การสร้างหน้าจอจัดการสินค้า ด้วย Rails scaffold framework

จากด้านบน เราได้เริ่มต้นสร้าง e-commerce application บน Rails ,สร้างฐานข้อมูล มีตารางชื่อ products และ config ไฟล์ให้ application สามารถติดต่อกับฐานข้อมูลได้ ซึ่งขั้นต่อไปจะเป็นการเขียนโปรแกรม สำหรับการจัดการรายการสินค้าส่วนของ admin ดังนี้

เปิด command

ecom_create_controller2.jpg

และเข้าไปยังไดเรกทอรี ecommerce โดยการพิมพ์

 > cd ecommerce
 > ruby script/generate scaffold Product Admin

NOTE:
จาก ruby script/generate scaffold Product Admin เป็นการสร้าง rails application พื้นฐานที่เราจะนำมาพัฒนาต่อ โดยพารามิเตอร์ Product คือ model และพารามิเตอร์ Admin คือ controller ซึ่งเมื่อมาตรวจสอบดูที่โปรแกรม Rad rails จะเห็นว่ามีการสร้างไฟล์ และไดเรกทอรีภายใต้ ไดเรกทอรี ecommerce มา ดังภาพ ด้านล่าง

ecom_scaffold.jpg

ecom_scaffold2.jpg

การเรียก web application

ecom_url.jpg

ecom_url_app.jpg

ecom_scaffold3.jpg

ecom_scaffold4.jpg

ecom_scaffold5.jpg

ecom_scaffold6.jpg

ecom_scaffold7.jpg

ecom_scaffold8.jpg

ecom_scaffold9.jpg

ecom_scaffold10.jpg

ecom_scaffold11.jpg

ecom_scaffold12.jpg


การปรับปรุงหน้าจอ

หน้า web site เดิม

ecom_scaffold9.jpg

ecom_code1.jpg

code เดิม

<h1>Listing products</h1>

<table>
  <tr>
  <% for column in Product.content_columns %>
    <th><%= column.human_name %></th>
  <% end %>
  </tr>

<% for product in @products %>
  <tr>
  <% for column in Product.content_columns %>
    <td><%=h product.send(column.name) %></td>
  <% end %>
    <td><%= link_to 'Show', :action => 'show', :id => product %></td>
    <td><%= link_to 'Edit', :action => 'edit', :id => product %></td>
    <td><%= link_to 'Destroy', { :action => 'destroy', :id => product }, :confirm => 'Are you sure?', :post => true %></td>
  </tr>
<% end %>
</table>

<%= link_to 'Previous page', { :page => @product_pages.current.previous } if @product_pages.current.previous %>
<%= link_to 'Next page', { :page => @product_pages.current.next } if @product_pages.current.next %> <br />

<%= link_to 'New product', :action => 'new' %>

เขียน views ชื่อ list.rhtml

code ใหม่

<h1>Product 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">

    <td>
      <img width="60" height="70" src="<%= product.image_url %>"/>
    </td>

    <td width="60%">
      <span><%= h(product.title) %></span><br />
      <%= h(truncate(product.description, 80)) %>
    </td>

    <td align="right">
      <%= product.date_available.strftime("%y-%m-%d") %><br/>
      <strong><%= sprintf("%0.2f", product.price) %> Bath</strong>
    </td>

    <td>
      <%= 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>

<%=  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' %>

หน้า web site ใหม่

ecom_scaffold13.jpg

แก้ไขรูปภาพ

จะเห็นว่ายังไม่มีรูปภาพ เนื่องจากเรายังไม่ได้เรารูปภาพไปใส่ใน ไดเรกทอรีที่ถูกต้อง ดังนั้นต้อง copy รูปภาพ (โดยชื่อรูปภาพจะเป็นชื่อที่เรากรอกใน form ข้างต้น ในที่นี้ คือ book1,book2 นั่นเอง) จึงจะแสดงรูปภาพดังนี้

ecom_copy_book.jpg

ecom_scaffold14.jpg

CSS ชื่อ scaffold.css”> แก้ไข CSS ชื่อ scaffold.css

ต่อไปเราจะเพิ่มความสวยงาม ให้หน้า web site ด้วยการแก้ไข stylesheet ที่มีมาให้กับ Scaffold Appliction อยู่แล้ว ที่ชื่อว่า “scaffold.css” อยู่ใน ../ecommerce/public/stylesheets/scaffold.css

ecom_code2.jpg

โดยเราจะเพิ่มข้อความเหล่านี้ลงไป ในไฟล์ scaffold.css

/* START:css */
.ListTitle { /* จัดรูปแบบตัวอักษรตรง title ของสินค้า*/
 font : bold smaller tahoma;
 color:     #244;
 font-size: 13px;
}

.ListActions {    /* จัดรูปแบบตัวอักษร ตรงเมนูจัดการรายการสินค้า show,edit,destroy*/
    font-size:    x-small;
 text-align:   right;
    padding-left: 1em;
}

.ListLine0 { /* เปลี่ยนสีพื้นหลังของสินค้า */
  background: #D6F7FE;
}

.ListLine1 {  /* เปลี่ยนสีพื้นหลังของสินค้า(สลับสีกับด้านบน) */
  background: #ECFCFF;
}
/* END:css */

ดังนี้

ecom_code3.jpg

จะได้หน้าของ การแสดงรายการสินค้า อย่างมีระเบียนและสวยงามยิ่งขึ้น ดังนี้

ecom_scaffold15.jpg


บทที่ 2 : สร้างส่วนการแสดงรายการสินค้าสำหรับลูกค้า (Catalog display)

Flow การสร้าง catalog

createCatalog2.png

ขั้นตอนการสร้างหน้าจอ catalog

1. สร้าง controller store_controller.rb
2. ดึงข้อมูลสินค้าจากฐานข้อมูล
  2.1 แก้ไข controllers ชื่อ store_controller.rb
  2.2 แก้ไข models ชื่อ product.rb
3. นำสินค้ามาแสดงผลผ่านหน้าจอ
  3.1 แก้ไข views ชื่อ index.rhtml
4. ปรับปรุงหน้าจอ
  4.1 สร้าง layouts ชื่อ store.rhtml
  4.2 สร้าง Style sheet (CSS)

สร้าง controller strore_controller.rb

เปิด command

ecom_create_controller2.jpg เข้าไปยังไดเรกทอรี ecommerce และพิมพ์

 >ruby script/generate controller Store index

ดังภาพ

ecom_cmd1.jpg

จะได้ผลลัพธ์ ดังภาพ

ecom_cmd2.jpg

จะเห็นว่ามีการสร้าง controller ขึ้นมาใหม่ (เรียกว่า StoreController?) โดยภายในมี method index()

เหตุผลในการสร้าง index() เพราะว่าเมื่อมีการเรียก URL มายัง Rails controller และไม่มีการระบุ action ต่อ ก็จะเรียกมาที่ index() อัตโนมัติ ดังนั้น หากเราเรียกไปที่ http://localhost:3000/store

ecom_code4.jpg

จะเห็นว่าไม่สามารถแสดงผลได้เนื่องจาก ไม่มีไฟล์ index.rhtml (ซึ่งต้องอยู่ในส่วนของ View)


ดึงข้อมูลสินค้าจากฐานข้อมูล

เขียน Controller

ดังนั้น เราจะเริ่มการเขียนโปรแกรม เพื่อแสดงรายการสินค้าสำหรับขาย และแสดงให้ลูกค้าดู โดยมีรูปแบบดังนี้

  • ดึงรายการสินค้าที่มีอยู่ใน database (ecommerce_development)
  • สินค้าที่แสดงจะต้องอยู่ในเงื่อนไขที่ว่า date_available <= now() (สินค้ามีแล้ว)
  • แสดงรายการสินค้า โดยเรียงตามวันที่ (date_available)
  • โดยลูกค้าสามารถดู และเลือกสินค้าลงตะกร้าได้ตามต้องการ (add to cart)

เขียนการแสดงผลในไฟล์ store_controller.rb ดังนี้

def index
  @products = Product.salable_items
end

ecom_seven1.jpg

ดึงข้อมูลสินค้าจากฐานข้อมูล

เขียน Model

ซึ่งยังไม่สามารถ run code ได้ในขณะนี้ เพราะเราต้องมี method salable_items() อยู่ใน Model product.rb ก่อน ดังนี้

def self.salable_items
    find(:all,
         :conditions => "date_available <= now()",
         :order      => "date_available desc")
end

ecom_seven2.jpg

อธิบายการเขียน code Model ใน product.rb

  • การเขียน code ใน product.rb นั้น จะมีการเรียกใช้ find() ซึ่งเป็น method ใน Rails
  • พารามิเตอร์ :all หมายถึง ทุกๆแถวที่เข้ากังเงื่อนไขที่กำหนด
  • เงื่อนไขที่กำหนด คือ date_available <= now() โดยใช้ function now() ซึ่งเป็นของ MySQL?
  • เงื่อนไขที่สอง คือเรียงลำดับการแสดงผลตามวันที่ date_available
  • Method find() จะ return row ของข้อมูลใน database ในรูปแบบของ Array แล้วส่งกลับไปให้ที่ controller (index.rhtml)

นำสินค้ามาแสดงผ่านหน้าจอ

แก้ไข Views ชื่อ index.rhtml

ต่อไปเราจะเขียนส่วนของ view template ซึ่งเป็นการแสดงผลทางหน้า web application

  • แก้ไขไฟล์ index.rhtml ที่ (app/view/store/index.rhtml)
  • ให้สังเกตว่า path ของ view นั้นจะสร้างจาก controller (store) และaction (index) ซึ่งจะต่อท้ายด้วย .rhtml แสดงว่าเป็น template
  • มี code ดังนี้
<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) %> Bath</strong>
      <%= link_to 'Add to Cart',
                  :action => 'add_to_cart',
                  :id     => product %>
      <br/>
    </td>
  </tr>
  <tr><td colspan="2"><hr/></td></tr>

<% end %>
</table>

ดังภาพ

ecom_seven3.jpg


ปรับปรุงหน้าจอ web site

สร้าง layouts ชื่อ store.rhtml

สังเกตว่า web site ส่วนใหญ่จะใช้ layout สำหรับการแสดงผลด้วยกัน ดังนั้นผู้ออกแบบควรมี layout template ซึ่งมันก็คือ มี header, footer, sidebar ของ website โดยส่วนต่างๆ เหล่านี้จะแยกออกจากเนื้อหาที่จะแสดงผล โดยผู้เขียน เขียน layout template เพียงแค่ครั้งเดียวหรือไฟล์เดียว แต่ทุกๆหน้าใน web site สามารถเรียกเอาไปใช้ได้ หากต้องการแก้ไขรูปแบบ web ก็สามารถแก้ไขที่ไฟล์เดียว

ดังนั้นเราต้องสร้างไฟล์ template ดังนี้

  • สร้างในไดเรกทอรีต่อไปนี้ app/view/layouts
  • สร้างไฟล์ template ชื่อเดียวกันกับ controller แต่ลงท้ายด้วย .rhtml
  • ดังนั้น เราต้องเขียนในไฟล์ชื่ิอ store.rhtml

ecom_seven5.jpg

ecom_seven6.jpg

ecom_seven7.jpg

  • เขียน code ดังนี้
<html>
    <head>
        <title>Books Online Store</title>
        <%= stylesheet_link_tag "catalog", :media => "all" %>
    </head>
    <body>
        <div id="banner">
            <%= @page_title || "Online Bookshelf" %>
        </div>
        <div id="columns">
            <div id="side">
                 <%= link_to 'Home', :action => 'index' %><br />
                <a href="#faq">Questions</a><br />
                <a href="#new">News</a><br />
                <a href="#contact">Contact</a><br />
                <%= link_to 'Site Admin', :controller => 'admin' , :action => 'index' %>
            </div>
            <div id="main">
                <%= @content_for_layout %>
            </div>
        </div>
    </body>
</html>

ecom_seven8.jpg


ปรับปรุงหน้าจอ web site

การสร้าง stylesheet ชื่อ catalog.css

* เขียนในไดเรกทอรี ecommerce/public/stylesheets * ชื่อไฟล์ catalog.css * มี code ดังนี้

#banner {
  background: #FFDCB9;  /* สี bg.banner*/
  padding-top: 40px;   /* ระยะห่างจากขอบด้านบน */
  padding-bottom: 40px; /* ระยะห่างจากขอบด้านล่าง */
  border-bottom: 2px solid; /* ใส่เส่นขอบด้านล่าง banner */
  font: small-caps 40px/40px "Times New Roman", serif; /* ปรับ font*/
  color: #FB7D00; /* ปรับสี font + กรอบล่าง*/
  text-align: center;  /* ตำแหน่งหัวข้อ */
}
#banner img {
  float: left;
}
#columns {
  background: #FFDCB9;
}

#main {
  margin-left: 10em;
  padding-top: 2ex;
  padding-bottom: 4ex;
  padding-left: 2em;
  background: white;
}

#side {
  float: left;
  padding-top: 1em;
  padding-left: 1em;
  padding-bottom: 1em;
  background: #FFDCB9;
  font: small sans-serif;
  /*font-weight: bold;*/
}

#notice {
  border: 2px solid red;
  padding: 1em;
  margin-bottom: 2em;
  background-color: #FFD7D7;
  font: bold smaller tahoma;
}

/* กรอบล้อมรอบ field ที่ทำให้เกิด error*/
.fieldWithErrors {
  width: 50%;
  padding: 1px;
  background-color: red;
  display: table;
}
/* กรอบล้อมรอบข้อความ error*/
#errorExplanation {
  width: 400px;
  border: 2px solid red;
  padding: 7px;
  padding-bottom: 12px;
  margin-bottom: 20px;
  background-color: #FFD7D7;
}
/* แสดง error ตรงหัวข้อบนสุด */
#errorExplanation h2 {
  text-align: left;
  font: bold 12px tahoma;
  padding: 5px 5px 5px 15px;
  font-size: 12px;
  margin: -7px;
  background-color: #c00;
  color: #fff;
}
#errorExplanation p {
  color: #333;
  margin-bottom: 0;
  padding: 5px;
}
/* แสดงข้อความบอก error */
#errorExplanation ul li {
  font: 12px tahoma;
  list-style: square;
}
a { /*ปรับสี font ของ link ต่างๆ*/
  text-decoration: none;
  font: smaller tahoma;
  color: #FB7D00;
}
a:hover {/*ปรับสี font link ถ้าเอาเมาส์ไปชี้*/
  color: #FF0000;
}
a.addtocart {
  padding-left: 1em;
  padding-right: 1em;
  color: #141;
  background: #cec;
  font-weight: bold;
}
a.addtocart:hover {
  color: #000000;
  background: #000000;
}
#side a { /*ปรับสีfont link ที่เมนูด้านซ้ายมือ*/
  font: smaller tahoma bold;
    color: #FB7D00;

}
#side a:hover {/*ปรับสี font link เมนูด้านซ้ายมือ ถ้าเอาเมาส์ไปชี้*/
  font: smaller tahoma bold;
  color : FF4500;
}
H2{
   font: smaller tahoma;
   color: #E20585;
   font-size: 16px;
}

H3{
   font-size: 150%;
   font-family: serif;
}
H3 {color: #FB7D00;}
bath{
   font: smaller tahoma;
   color : #FF80C0;
}

/**** styles for the catalog ***/
/* === Use the Holly Hack on .catalogentry === */
/* Hide from IE-mac \*/
* html .catalogentry { height: 1%; }
/* End hide from IE-mac */
.catalogentry {
  padding: 1ex 0ex;
}
.catalogentry img {
  float: left;
  margin-right: 2em;
}
.catalogentry h3 {
  font: larger bold;
  color: #282;
  margin-top: 0ex;
  margin-bottom: 0.5ex;
}
.catalogentry p {
  font: smaller tahoma;
  margin-bottom: .5ex;
}
.catalogprice {
  padding-right: 4em;
}
/* Shopping cart screen */
.carttitle {
  background: #FB7D00;
  color: #FFFFFF;
  font: bold smaller tahoma ;
  text-align: center;
}
.carttitle TD { /*ปรับสีหัวตาราง */
  background : #FB7D00;
  padding-top: 1px;
  padding-bottom: 1px;
}
.carttitle TR {
  background : #FEDEF0;
  padding-top: 1px;
  padding-bottom: 1px;
}
.carttotal{
  font: bold smaller tahoma;
  color: #000099;

}
.add_quantity{
  background : #0C0F81;
  font: bold smaller tahoma ;
  color: #FFFFFF;
  text-align: center;

}
#cartmenu {
  font: smaller tahoma ;
  color: #FB7D00;
  float: right;
  border-left: 1px dotted #000282; /*เส้นคั่น เมนูย่อย*/
}
#totalcell {
  font-weight: bold;
  border-top: 1px solid #000282;
  border-bottom: 2px solid #000282;
}

.separator {
  border-bottom: 1px dotted #282;
  clear: both;
}
.ListLine0 {
  background: #FFD9B3;
  font: smaller tahoma;
}

.ListLine1 {
  background: #FFE7CE;
   font: smaller tahoma;
}

ดังนี้

ecom_seven9.jpg

ecom_seven10-2.jpg

ecom_seven11-1.jpg

ecom_scaffold16.jpg