ต่อจากคราวที่แล้ว มันยังไม่จบนะครับ มันยังมีสิ่งที่น่าสนใจอยู่อีก
ในทุกๆ วันนี้ database เห็นจะแยกออกจาก web application ไม่ได้ซะแล้ว ไม่ว่าจะทำอะไร จะทำเว็บขายของ หรือแม้กระทั้ง text base อย่าง blog หรือเว็บข่าวสาร ก็ยังคงต้องใช้ database ในการเก็บข้อมูล หนีไม่พ้น
ตอนนี้เราใช้ database แบบ relation ซึ่งแบบ relation เนี่ย มันเป็นสิ่งที่ดีสำหรับการออกแบบ สำหรับการที่จะเข้ามาดูมัน ดูแล้วมันเข้าใจง่ายๆ แต่มันทำให้ยากที่จะเชื่อมต่อระหว่าง database แบบ relation กับภาษาเชิง OO ซึ่ง Object นั้น เป็นทุกๆ อย่าง เป็นข้อมูล เป็น operations และ database ก็เป็นชุดของข้อมูล มันง่ายสำหรับการมองอย่าง relation แต่มันก็เป็นสิ่งที่ยากถ้ามองอย่าง OO
ถ้าเราเขียนโปรแกรมต่อ database โดยใช้ภาษาเชิง procedural อย่าง C เป็นต้น เราก็ต้องเขียน sql command ลงไปใน code ของเรา หรือจะใช้ preprocessor ทำการ convert sql ไว้ก่อน แล้วค่อยเรียกเข้ามาใช้งาน ในตัวงานของเราก็จะผสมปนเประหว่าง logic ของตัว database กับ logic ของงานของเรา ใครที่เคยเขียนมา ก็คงจะเข้าใจ ว่ามันจะอิรุงตุงนังกันขนาดไหน เวลาจะเอางานเก่ามาแก้ทีนึง หรือเอามาปรับปรุง ต่อยอด มันจะงงๆ แน่นอน (ฉันทำอะไรลงไปเนี่ย) ดูยุ่งเหยิง การเขียนแบบนี้ เขาก็ใช้กันทั่วๆ ไป แต่มันจะเหมาะสำหรับงานเล็กๆ มากกว่า แล้วเราต้องมาเรียนรู้ sql กันอีก กว่าจะทำงานพวกนี้ได้ ถ้ามีการต้องต่อกับ database อีก เหมือนๆ ของเดิม แต่เป็นที่อื่น เราก็แค่ copy code ไปวางไว้ที่ๆ นั้น ถ้างานเราใหญ่มากๆ copy ไปๆ มา จะมึนซะอีก มันดูไม่ค่อยสวยเลยแฮะ
แต่ในภาษาเชิง OO ที่เรารู้จัก การทำ encapsulation มันจะแก้ปัญหาพวกนี้ออกไป มันจะห่อของพวกนี้ ไว้ในกลุ่มๆ นึง ที่เราเรียกกันว่า class ซึ่งเราจะสร้างเจ้า class นี้ เพียงก้อนเดียว ก็สามารถทำการเปลี่ยนแปลงเจ้าความวุ่นวายข้างบนได้แล้ว
แล้วก็มีพวกมนุษย์หัวใส ได้ต่อเติมความคิดแบบนี้สำหรับการเขียนโปรแกรมกับ database เขาห่อพวก code ที่จะทำการติดต่อกับ database ไว้ภายใต้ class อันนึง เวลาเราจะใช้งาน ก็มาเรียกผ่าน class อันนี้ การที่จะห่อ code พวกนี้ ไว้ภายใต้ class จะต้องห่อเจ้าพวก schema ลงไปด้วย แล้วแยก business logic ออกจากระดับ low-level(sql command ต่างๆ) มันดูยากถ้าจะเอามาเขียนโปรแกรมจริงๆ เพราะ database จริงๆ มันจะติดต่อกับอะไรบ้างก็ไม่รู้ แต่ถ้าเรามามองการติดต่อกันนัวเนียๆ ในรูป Object ล่ะ มันดูยากแน่ๆ แต่แล้วอุตสาหกรรมคอมพิวเตอร์ ก็สร้างมันออกมาได้ มันคือ ORM หรือ Object/Relation Mapping ซึ่ง Rails ก็ใช้ ORM นี้เหมือนกัน
Object/Relation Mapping
ORM มันจะทำการจับคู่ ผูก(map) เชื่อมต่อกับ table ใน database ให้เป็น class ถ้าเกิด table ของเราชื่อ Orders หลังจากการ map ไปแล้ว จะได้ class ที่ชื่อว่า Order แต่ละ row ใน table ก็จะเหมือน object ของ class อันนี้ ส่วน column ก็จะกลายเป็น attribute ของ object นั้นๆ ไป แล้วใน class นี้ ก็จะมี method สำหรับ query ค่าออกมา
จากที่กล่าวมา class ของ Rails จะทำการห่อหุ้ม table ของ database เอาไว้ แล้วแบ่งออกเป็นระดับ ส่วนที่เป็น class จะทำหน้าที่เหมือน table มาดูตัวอย่าง เราต้องการหา order จาก id
order = Order.find(1)
puts "Order #{order.customer_id}, amount=#{order.amount}"
|
ผลของตัวอย่างนี้ จะ return ค่าออกมาเป็น object ที่เป็นของ Order class
หรือถ้าต้องการให้มันออกมาเป็นกลุ่มๆ
Order.find(:all, :conditions => "name='dave'") do |order|
puts order.amount
end
|
หรือถ้าจะทำการ save(หรือ update, delete) อะไรลงใน database
Order.find(:all, :conditions => "name='dave&'") do |order|
order.discount = 0.5
order.save
end
|
นี่เป็นตัวอย่าง code เล็กๆ น้อยๆ
สำหรับ ORM library ทั่วๆ ไป การท่จะใช้งาน เราต้องมา configure อะไรอีกตั้งเยอะตั้งแยะ แต่ถ้าใช้ ORM tools ก็จะสบายหน่อย มีเครื่องไม้เครื่องมือ คอยช่วยสร้างตัว configuration(ส่วนใหญ่จะเห็นเป็น XML) ต่างๆ
Active Record
กว่าจะมาถึง Active Record ยืดยาวจริง
Active Record คือ ชั้นของ ORM ของ Rails มีลักษณะเหมือนๆ กับ ORM model ทั่วๆ ไป คือ table จะ map เป็น class แล้ว row เป็น record แล้ว column เป็น attribute ของ object นั้นๆ แต่มันก็ต่างจาก ORM library ตัวอื่นๆ ตรงวิธีในการ configure เราจะทำการ configure มันตั้งแต่ตอนต่อกับ database เพียงทีเดียว แล้วมันจะจัดการให้หมดทุกอย่าง มาดูตัวอย่าง code ง่ายๆ สำหรับ Active Record
1
2
3
4
5
6
| require "active_record"
class Order < ActiveRecord::Base
end
order = Order.find(1)
order.discount = 0.5
order.save
|
code นี้ จะทำการ new Order ขึ้นมาใหม่ แล้วทำการค้นหาโดย id แล้วทำการเซ็ตค่าให้กับ object(หรือ row) นั้นๆ แล้วทำการ save มันกลับลงไป แต่จริงๆ แล้ว Active Record ทำได้มากกว่านี้ ถ้าเราพัฒนางานบน Rails เรายังสามารถสั่งการ validate ข้อมูลได้อีกด้วย ถ้ามันมี error ก็ยังสามารถแสดง error นั้น ไปยังฝั่ง view ได้อีก ไว้มาดูตัวอย่างกันคราวหลัง
แก้ไขล่าสุด วันที่ 5 กรกฏาคม 2550 เวลา 1.44 น.