Eloquent ORM: คุยกับฐานข้อมูลแบบมนุษย์ด้วย Model

1. 🎯 ชื่อตอน (Title): ตอนที่ 21: Eloquent ORM ล่ามแปลภาษาส่วนตัว คุยกับฐานข้อมูลให้เป็นภาษาคนด้วย Model
2. 📖 เปิดฉาก (The Hook):
มาครับน้องๆ ลากเก้าอี้มานั่งจิบกาแฟกัน… ถ้าย้อนกลับไปยุคที่เราเขียน PHP ต่อฐานข้อมูลใหม่ๆ เราคงหนีไม่พ้นการเขียนโค้ด SQL ดิบๆ (Raw SQL) เช่น SELECT * FROM users WHERE status = 1 แปะไว้กลางโค้ด PHP เลยใช่ไหมครับ?
ตอนโปรเจกต์ยังเล็กมันก็ดูไม่มีปัญหาอะไรหรอกครับ แต่พอดาต้าเบสเริ่มใหญ่ มีการ Join ตาราง 4-5 ตาราง โค้ด SQL ของเราจะยาวเป็นหางว่าว อ่านยาก แก้ไขลำบาก แถมถ้าวันดีคืนดีบอสสั่งเปลี่ยนจาก MySQL ไปใช้ PostgreSQL ขึ้นมา… งานงอกสิครับ! ต้องมานั่งไล่แก้ SQL Syntax ใหม่ทั้งโปรเจกต์ (Pain Point ระดับตำนาน!)
เพื่อแก้ปัญหานี้ วิศวกรซอฟต์แวร์จึงคิดค้นเทคนิคที่เรียกว่า ORM ขึ้นมา และในโลกของ Laravel เรามีพระเอกสุดหล่อที่ชื่อว่า “Eloquent ORM” ครับ มันเปรียบเสมือน “ล่ามส่วนตัว (Translator)” ที่ช่วยแปลงคำสั่งภาษาอังกฤษง่ายๆ ของเรา ให้กลายเป็นคำสั่ง SQL สุดซับซ้อนไปคุยกับฐานข้อมูลแทนเรา วันนี้พี่จะพาไปดูว่า การคุยกับดาต้าเบสแบบมนุษย์คุยกัน มันสวยงามและประหยัดเวลาขนาดไหน!
3. 🧠 แก่นวิชา (Core Concepts):
ก่อนจะไปเขียนโค้ด เรามาทำความเข้าใจคอนเซปต์ของ ORM กันก่อนครับ:
- 🪄 ORM (Object-Relational Mapping) คืออะไร?
อธิบายง่ายๆ มันคือการ “จับคู่ (Mapping)” โลกของฐานข้อมูล (Relational Database) ให้กลายเป็นโลกของการเขียนโปรแกรมเชิงวัตถุ (Object-Oriented) ครับ โดยมีกฎเหล็ก 3 ข้อคือ:
- Table (ตาราง) = กลายเป็น Class ที่เรียกว่า Model
- Column (คอลัมน์) = กลายเป็น Attributes (ตัวแปร) ของคลาส
- Row (ข้อมูล 1 แถว) = กลายเป็น Object (อินสแตนซ์) 1 ตัว
- 🤖 กฎการตั้งชื่อของ Eloquent (Model Conventions)
Laravel มีความฉลาด(และแอบเดาใจเก่ง) มากครับ เมื่อเราสร้าง Model ชื่อว่า
Flight(เอกพจน์/ตัวพิมพ์ใหญ่) Eloquent จะวิ่งไปหาตารางที่ชื่อว่าflights(พหูพจน์/ตัวพิมพ์เล็ก/Snake Case) ในฐานข้อมูลให้แบบอัตโนมัติ โดยที่เราไม่ต้องบอกมันเลย! - 🔑 Primary Key และ Timestamps
ตามค่าเริ่มต้น Eloquent จะถือว่าทุกตารางต้องมีคอลัมน์
idเป็น Primary Key เสมอ และจะมีคอลัมน์created_atกับupdated_atเพื่อเอาไว้บันทึกเวลาสร้างและแก้ไขข้อมูลโดยอัตโนมัติ

4. 💻 ร่ายมนต์โค้ด (Show me the Code):
เรามาดูวิธีการใช้งานจริงกันครับ สมมติว่าเรามีตาราง flights (เที่ยวบิน) เราจะเริ่มจากการสร้าง Model ก่อน
1. การสร้าง Model
# ใช้ Artisan สร้าง Model พร้อมกับไฟล์ Migration ในคำสั่งเดียวเลย
php artisan make:model Flight -m2. การดึงข้อมูล (Select / Read) การดึงข้อมูลใน Eloquent จะอ่านง่ายเหมือนภาษาอังกฤษเลยครับ
use App\Models\Flight;
// ดึงข้อมูลเที่ยวบินทั้งหมด (SELECT * FROM flights)
$flights = Flight::all();
// ดึงข้อมูลเที่ยวบินที่ id = 1
$flight = Flight::find(1);
// ดึงแบบมีเงื่อนไข (SELECT * FROM flights WHERE active = 1 ORDER BY name)
$activeFlights = Flight::where('active', 1)
->orderBy('name')
->take(10)
->get();3. การเพิ่มข้อมูลใหม่ (Insert / Create) เรามองว่าข้อมูล 1 แถว คือ Object 1 ตัว ดังนั้นเราจึงสร้าง Object ใหม่ กำหนดค่า แล้วสั่ง Save ได้เลย!
use App\Models\Flight;
// สร้าง Object เที่ยวบินใหม่
$flight = new Flight;
// กำหนดค่าให้แต่ละคอลัมน์
$flight->name = 'Bangkok to Tokyo';
$flight->airline = 'Epic Air';
// สั่งบันทึกลงฐานข้อมูล (ระบบจะเติม created_at และ updated_at ให้เองด้วย!)
$flight->save();4. การแก้ไขข้อมูล (Update)
การอัปเดตก็เหมือนกับการสร้างครับ แค่เปลี่ยนจากการ new เป็นการ find เพื่อดึงของเก่าขึ้นมาก่อน
use App\Models\Flight;
// หาเที่ยวบินที่ id = 1 ขึ้นมาก่อน
$flight = Flight::find(1);
// เปลี่ยนชื่อ
$flight->name = 'Bangkok to Osaka';
// สั่งบันทึกทับลงไป
$flight->save();5. 🛡️ เคล็ดลับจากคัมภีร์ลับ (Under the Hood / Pro-Tips):
- 🚨 การป้องกัน Mass Assignment:
นอกจากการใช้
save()แล้ว เรายังสามารถใช้คำสั่ง$flight = Flight::create(['name' => 'Tokyo']);เพื่อบันทึกข้อมูลแบบยัดทีเดียวทั้งก้อน (Mass Assignment) ได้ด้วย แต่ระวัง! เพื่อป้องกันแฮกเกอร์แอบส่งคอลัมน์แปลกๆ (เช่นis_admin = 1) เข้ามา Laravel จึงบังคับให้เราต้องไปประกาศตัวแปร$fillableใน Model เสียก่อน เพื่อบอกว่า “อนุญาตให้คอลัมน์ไหนบันทึกแบบกลุ่มได้บ้าง”class Flight extends Model { protected $fillable = ['name', 'airline']; // อนุญาตแค่นี้ } - 🔍 ทริคการหาข้อมูล
findOrFail(): เวลาเราดึงข้อมูลด้วยfind($id)ถ้าไม่เจอข้อมูล มันจะคืนค่ากลับมาเป็นnullซึ่งอาจทำให้เว็บพังตอนเอาไปแสดงผล พี่แนะนำให้ใช้findOrFail($id)แทนครับ เพราะถ้ามันหาไม่เจอ มันจะโยนหน้า Error 404 (Not Found) กลับไปให้ผู้ใช้งานทันที โคตรจะสะดวก! - 🗑️ ไม่ได้ลบ แต่แค่ซ่อน (Soft Deletes):
หากตารางไหนข้อมูลสำคัญมาก เราสามารถใส่ Trait
use SoftDeletes;เข้าไปใน Model ได้ เมื่อเราสั่ง$flight->delete();ระบบจะไม่ลบข้อมูลทิ้งจริงๆ ครับ แต่จะไปประทับเวลาในช่องdeleted_atแทน ทำให้ข้อมูลนั้นถูกซ่อนไป (กู้คืนได้เสมอ)
6. 🏁 บทสรุป (To be continued…):
เป็นอย่างไรกันบ้างครับกับเวทมนตร์ของ Eloquent ORM? มันช่วยซ่อนความซับซ้อนของฐานข้อมูล (Database Abstraction) เอาไว้เบื้องหลัง ทำให้โค้ดของเราสะอาดขึ้น อ่านง่ายเหมือนภาษาอังกฤษ และที่สำคัญคือเราสามารถมีสมาธิกับการจัดการ “Business Logic” โดยไม่ต้องไปพะวงกับ SQL Syntax อีกต่อไป
แต่เดี๋ยวก่อน! ความเทพของ Eloquent ยังไม่หมดแค่นี้ ในโลกความเป็นจริง ตารางต่างๆ มันต้องมีความเกี่ยวข้องกัน (เช่น ผู้ใช้ 1 คน มีบทความได้หลายบทความ) ในตอนหน้า พี่จะพาไปเจาะลึกสุดยอดคัมภีร์ของ ORM นั่นก็คือ “Eloquent Relationships (ความสัมพันธ์ของตาราง)” เตรียมกาแฟแก้วใหญ่ๆ ไว้ได้เลย แล้วพบกันครับ!
ต้องการที่ปรึกษาและพัฒนาระบบ Automation ให้กับโรงงานของคุณ? ทีมงาน WP Solution พร้อมให้บริการออกแบบและติดตั้งระบบแบบครบวงจร ดูรายละเอียดบริการของเราได้ที่: www.wpsolution2017.com หรือพูดคุยปรึกษาเบื้องต้นได้ที่ Line: wisit.p