แต่ควายข้ายังอยู่เมืองนอกนี่หว่า จะให้ข้าเลิกได้ไง
อิอิ
คนเขียนบทนี่เหลือเกินจริงๆ
วันจันทร์, กรกฎาคม 30, 2550
วันพฤหัสบดี, กรกฎาคม 05, 2550
อ่าน Agile Web Development with Rails ( 11 )
ทีนี้มาดูว่าเขาใช้ AJAX ใน Rails กันอย่างไร
ปกติเราใส่ปุ่มเข้าไปใน Rails โดยแทรกโค้ดง่ายๆดังนี้
<%= button_to "Add to Cart" , :action => :add_to_cart, :id => product %>
ซึ่งในเวลาทำงานจะสร้างโค้ด html อย่างนี้
<form method="post" action="/store/add_to_cart/1" class="button-to" >
<input type="submit" value="Add to Cart" />
</form>
เราเอา AJAX มาใช้ตรงนี้โดยการแทนที่แท็ก button_to โดยโค้ดนี้
<% form_remote_tag :url => { :action => :add_to_cart, :id => product } do %>
<%= submit_tag "Add to Cart" %>
<% end %>
คำสั่ง form_remote_tag ใช้สร้างฟอร์ม โดยโค้ดระหว่างบล็อก do - end จะเป็น elements ในฟอร์มที่สร้างขึ้น
นอกจากนี้ เพื่อให้ Rails รับรู้การใช้งาน AJAX เราต้องไปเพิ่มคำสั่ง javascript_include_tag ที่ head ใน app/views/layouts/store.rhtml ดังนี้
<head>
<title>Pragprog Books Online Store</title>
<%= stylesheet_link_tag "depot" , :media => "all" %>
<%= javascript_include_tag :defaults %>
</head>
โค้ดที่เขียนขึ้นจะถูกเรียกโดย add_to_cart แต่เราจะไม่ใช้ app/views/store/add_to_cart.rhtml อันเก่า (ลบทิ้งซะ) แต่จะใช้ app/views/store/add_to_cart.rjs แทน ดังนี้
page.replace_html("cart" , :partial => "cart" , :object => @cart)
เช่นนี้เอง
ปกติเราใส่ปุ่มเข้าไปใน Rails โดยแทรกโค้ดง่ายๆดังนี้
<%= button_to "Add to Cart" , :action => :add_to_cart, :id => product %>
ซึ่งในเวลาทำงานจะสร้างโค้ด html อย่างนี้
<form method="post" action="/store/add_to_cart/1" class="button-to" >
<input type="submit" value="Add to Cart" />
</form>
เราเอา AJAX มาใช้ตรงนี้โดยการแทนที่แท็ก button_to โดยโค้ดนี้
<% form_remote_tag :url => { :action => :add_to_cart, :id => product } do %>
<%= submit_tag "Add to Cart" %>
<% end %>
คำสั่ง form_remote_tag ใช้สร้างฟอร์ม โดยโค้ดระหว่างบล็อก do - end จะเป็น elements ในฟอร์มที่สร้างขึ้น
นอกจากนี้ เพื่อให้ Rails รับรู้การใช้งาน AJAX เราต้องไปเพิ่มคำสั่ง javascript_include_tag ที่ head ใน app/views/layouts/store.rhtml ดังนี้
<head>
<title>Pragprog Books Online Store</title>
<%= stylesheet_link_tag "depot" , :media => "all" %>
<%= javascript_include_tag :defaults %>
</head>
โค้ดที่เขียนขึ้นจะถูกเรียกโดย add_to_cart แต่เราจะไม่ใช้ app/views/store/add_to_cart.rhtml อันเก่า (ลบทิ้งซะ) แต่จะใช้ app/views/store/add_to_cart.rjs แทน ดังนี้
page.replace_html("cart" , :partial => "cart" , :object => @cart)
เช่นนี้เอง
วันพุธ, กรกฎาคม 04, 2550
อ่าน Agile Web Development with Rails ( 10 )
ทีนี้เรื่อง partial templates หรือที่เรียกย่อๆว่า partials
ลองดูโค้ดนี้
<table>
<% for cart_item in @cart.items %>
<tr>
<td><%= cart_item.quantity %>×</td>
<td><%= h(cart_item.title) %></td>
<td class="item-price" ><%= number_to_currency(cart_item.price) %></td>
</tr>
<% end %>
<tr class="total-line" >
<td colspan="2" >Total</td>
<td class="total-cell" ><%= number_to_currency(@cart.total_price) %></td>
</tr>
</table>
เขียนใหม่โดยใช้ partials ได้อย่างนี้
<table>
<%= render(:partial => "cart_item" , :collection => @cart.items) %>
<tr class="total-line" >
<td colspan="2" >Total</td>
<td class="total-cell" ><%= number_to_currency(@cart.total_price) %></td>
</tr>
</table>
ส่วน cart_item จะแยกไว้อีกไฟล์หนึ่ง app/views/store/_cart_item.rhtml
<tr>
<td><%= cart_item.quantity %>×</td>
<td><%= h(cart_item.title) %></td>
<td class="item-price" ><%= number_to_currency(cart_item.price) %></td>
</tr>
คำสั่ง render ในไฟล์แรกจะแสดงผล app/views/store/_cart_item.rhtml (โปรดสังเกตว่ามี _ นำหน้า) โดยจะวนลูปให้อัตโนมัติครับ
วิธีนี้ทำให้เราสามารถเขียน partials ไปแปะแทรกไว้ที่ไหนก็ได้ที่ต้องการได้ทุกเมื่อครับ
ลองดูโค้ดนี้
<table>
<% for cart_item in @cart.items %>
<tr>
<td><%= cart_item.quantity %>×</td>
<td><%= h(cart_item.title) %></td>
<td class="item-price" ><%= number_to_currency(cart_item.price) %></td>
</tr>
<% end %>
<tr class="total-line" >
<td colspan="2" >Total</td>
<td class="total-cell" ><%= number_to_currency(@cart.total_price) %></td>
</tr>
</table>
เขียนใหม่โดยใช้ partials ได้อย่างนี้
<table>
<%= render(:partial => "cart_item" , :collection => @cart.items) %>
<tr class="total-line" >
<td colspan="2" >Total</td>
<td class="total-cell" ><%= number_to_currency(@cart.total_price) %></td>
</tr>
</table>
ส่วน cart_item จะแยกไว้อีกไฟล์หนึ่ง app/views/store/_cart_item.rhtml
<tr>
<td><%= cart_item.quantity %>×</td>
<td><%= h(cart_item.title) %></td>
<td class="item-price" ><%= number_to_currency(cart_item.price) %></td>
</tr>
คำสั่ง render ในไฟล์แรกจะแสดงผล app/views/store/_cart_item.rhtml (โปรดสังเกตว่ามี _ นำหน้า) โดยจะวนลูปให้อัตโนมัติครับ
วิธีนี้ทำให้เราสามารถเขียน partials ไปแปะแทรกไว้ที่ไหนก็ได้ที่ต้องการได้ทุกเมื่อครับ
วันอังคาร, กรกฎาคม 03, 2550
อ่าน Agile Web Development with Rails ( 9 )
เก็บหนังสือไปนาน กลับมาอ่านกันต่อครับ
มาดูการจัดการ error บ้าง สิบปากว่าไม่เท่าตาเห็น ดูโค้ดเอาเองก็แล้วกัน
app/controllers/store_controller.rb
def add_to_cart
begin
product = Product.find(params[:id])
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid product #{params[:id]}" )
flash[:notice] = "Invalid product"
redirect_to :action => :index
else
@cart = find_cart
@cart.add_product(product)
end
end
คราวนี้ถ้าเรียก http://localhost:3000/store/add_to_cart/wibble แทนที่จะเจอ error เจ้า error ก็จะไปอยู่ใน log/development.log แล้ว อย่างงว่า wibble คืออะไร สำหรับ Rails แล้ว สิ่งที่ใส่ต่อท้ายก็คือ parameter ID นั่นไงครับ
ปัญหาอีกอย่าคือ error message ที่เราคาดหวังยังไม่โผล่ ต้องไปใส่โค้ดนี้ที่ app/views/layouts/store.rhtml ด้วย
<% if flash[:notice] -%>
<div id="notice" ><%= flash[:notice] %></div>
<% end -%>
โดยทั่วไปจะไว้บบบนสุดก่อนข้อความอื่นใดนะครับ
มาดูการจัดการ error บ้าง สิบปากว่าไม่เท่าตาเห็น ดูโค้ดเอาเองก็แล้วกัน
app/controllers/store_controller.rb
def add_to_cart
begin
product = Product.find(params[:id])
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid product #{params[:id]}" )
flash[:notice] = "Invalid product"
redirect_to :action => :index
else
@cart = find_cart
@cart.add_product(product)
end
end
คราวนี้ถ้าเรียก http://localhost:3000/store/add_to_cart/wibble แทนที่จะเจอ error เจ้า error ก็จะไปอยู่ใน log/development.log แล้ว อย่างงว่า wibble คืออะไร สำหรับ Rails แล้ว สิ่งที่ใส่ต่อท้ายก็คือ parameter ID นั่นไงครับ
ปัญหาอีกอย่าคือ error message ที่เราคาดหวังยังไม่โผล่ ต้องไปใส่โค้ดนี้ที่ app/views/layouts/store.rhtml ด้วย
<% if flash[:notice] -%>
<div id="notice" ><%= flash[:notice] %></div>
<% end -%>
โดยทั่วไปจะไว้บบบนสุดก่อนข้อความอื่นใดนะครับ
สมัครสมาชิก:
บทความ (Atom)