การใช้ Enum เพื่ออ้างอิงค่าตัวเลขในระบบและลดความสับสนในการตีความหมาย ใน Laravel

ในการพัฒนาระบบ มักมีการกำหนดค่าคงที่  เพื่อใช้แทนสถานะหรือประเภทข้อมูลต่าง ๆ ภายในระบบ เช่น สถานะการยืมอุปกรณ์ สถานะการประชุม หรือสถานะการอนุมัติเอกสาร โดยทั่วไปข้อมูลเหล่านี้จะถูกจัดเก็บในฐานข้อมูลเป็นตัวเลขหรือรหัสสั้น ๆ เพื่อความสะดวกในการจัดเก็บและประมวลผล

ตัวอย่าง เช่น
1 = รออนุมัติ
2 = ระหว่างดำเนินการ
3 = อนุมัติแล้ว
4 = เสร็จสิ้น

ในช่วงแรกของการพัฒนาระบบ อาจเขียนเงื่อนไขโดยอ้างอิงค่าตัวเลขโดยตรง

if ($booking->status_id == 2) {
    // ระหว่างดำเนินการ
}

แม้ว่าวิธีดังกล่าวจะสามารถใช้งานได้ แต่เมื่อระบบมีขนาดใหญ่ขึ้นและมีการใช้งานสถานะเดิมในหลายส่วนของระบบ การอ้างอิงตัวเลขโดยตรงอาจทำให้อ่านโค้ดยาก และเกิดความสับสนได้ว่าตัวเลขแต่ละค่าหมายถึงอะไร Laravel จึงมีการรองรับการใช้งาน Enum เพื่อช่วยให้การจัดการค่าคงที่มีความชัดเจน อ่านง่าย และเข้าใจความหมายได้ทันที

ตัวอย่างปัญหาที่พบ

if ($booking->status_id == 1) {
    // รออนุมัติ
}

if ($booking->status_id == 2) {
    // ระหว่างดำเนินการ
}

if ($booking->status_id == 3) {
    // อนุมัติแล้ว
}

เมื่อกลับมาอ่านโค้ดในภายหลัง อาจต้องเสียเวลาเปิดตารางสถานะเพื่อดูว่าตัวเลขแต่ละค่าหมายถึงอะไร นอกจากนี้ หากมีการเปลี่ยนแปลงค่าในอนาคต จำเป็นต้องแก้ไขโค้ดหลายจุดภายในระบบ

แนวทางการพัฒนา
สร้าง Enum สำหรับเก็บสถานะ โดยสร้างไฟล์ ภายในโฟลเดอร์ app\Enums

namespace App\Enums;

enum BookingStatus: int
{
    case WAITING_APPROVE = 1;
    case PROCESSING = 2;
    case APPROVED = 3;
    case COMPLETED = 4;
}


การเรียกใช้งาน

จากเดิม

if ($booking->status_id == 2) {
    // รออนุมัติ
}

เปลี่ยนเป็น

if ($booking->status_id == BookingStatus::PROCESSING->value) {
    // ระหว่างดำเนินการ
}

มีอีกวิธีหนึ่งที่ช่วยให้ไม่ต้องเรียกใช้ ->value คือ การกำหนด Enum ไว้ใน $casts ของ Model เพื่อให้ Laravel แปลงค่าจากฐานข้อมูลเป็น Enum โดยอัตโนมัติ เมื่อเรียกใช้งานจึงสามารถเปรียบเทียบกับ Enum ได้โดยตรง

ตัวอย่าง ภายใน Model ของ Class BookingStatus

protected $casts = [
   'status_id' => BookingStatus::class,
];

Laravel จะทำการแปลงค่าจากฐานข้อมูล เช่น status_id = 2 ให้กลายเป็น Enum
BookingStatus::PROCESSING จึงสามารถเรียกใช้งานได้โดยไม่ต้องใช้ ->value

การเรียกใช้งาน

if ($booking->status_id == BookingStatus::PROCESSING) {
    // ระหว่างดำเนินการ
}

แม้จะเป็นเงื่อนไขเดียวกัน แต่การเขียนเรียกใช้งานดังกล่าว ผู้พัฒนาจะสามารถเข้าใจความหมายได้ทันทีโดยไม่ต้องตรวจสอบว่าค่า 2 หมายถึงอะไร

ข้อดี

  1. ทำให้อ่านโค้ดง่ายขึ้น ช่วยให้เข้าใจความหมายได้ทันที
  2. ไม่ต้องจำว่าตัวเลขแต่ละค่าหมายถึงอะไร
  3. ลดความผิดพลาดในการพัฒนา
  4. ดูแลรักษาระบบได้ง่ายขึ้น เมื่อมีการเพิ่มหรือแก้ไขสถานะ สามารถจัดการได้จากจุดเดียว


ผู้เขียน