Category Archive Laravel

Byphunsanit

Laravel: DataTables & Eloquent

โดยปกติของมนุษย์ framework ถ้าเขียน Laravel และใช้ DataTables โดยปกติจะใช้ Laravel DataTables Documentation หรือ ที่ใน composer คือ composer require yajra/laravel-datatables:^11.0 แต่คิดว่า รูปแบบเงื่อนไขที่ต้องการ เขียนเองโดยใช้ Laravel กับ Eloquent น่าจะได้ตามที่ต้องการมากกว่า เลยเขียนมันเอง น่าจะถูกใจมากกว่า

ก่อนอื่นต้องเข้าใจว่า DataTable มีการ รับส่งข้อมูลเป็น rest api ง่าย ๆ ตามคู่มือ Server-side processing ถ้าส่งข้อมูลได้ตรงกับที่ต้องการ มันก็ทำงานได้ ตัว library ด้านบนมันก็ทำงานแบบนี้ เราสามารถแก้ laravel Controller ได้เหมือนกัน

    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {
        if ($request->ajax()) {
            $json = [
                'data' => [],
                'draw' => $request->input('draw', 1),
                'recordsFiltered' => 0,
                'recordsTotal' => 0,
            ];

            $query = Ticket::query();
            $json['recordsTotal'] = $query->count();

            if ($request->has('search') && !empty($request->search)) {

                if (!empty($request->search['id']) && is_int((int) $request->search['id'])) {
                    $query->where('id', (int) $request->search['id']);
                }

                if ($request->search['category_id'] && is_int((int) $request->search['category_id'])) {
                    $query->where('category_id', $request->search['category_id']);
                }

                if ($request->search['service_lines_id'] && is_int((int) $request->search['service_lines_id'])) {
                    $query->where('service_lines_id', $request->search['service_lines_id']);
                }

                if ($request->search['status_id'] && is_int((int) $request->search['status_id'])) {
                    $query->where('status_id', $request->search['status_id']);
                }

                if ($request->search['support_engineer_id'] && is_int((int) $request->search['support_engineer_id'])) {
                    $query->where('support_engineer_id', $request->search['support_engineer_id']);
                }

            }

            $json['data'] = $query->get()->map(function ($ticket) {
                return [
                    'id' => $ticket->id,
                    'category_id' => $ticket->category_id,
                    'vessel_id' => $ticket->vessel_id,
                    'service_lines_id' => $ticket->service_lines_id,
                    'support_engineer_id' => $ticket->support_engineer_id,
                    'sla_dt' => $ticket->sla_dt,
                    'working_time' => $ticket->working_time,
                ];
            })
                ->skip(request()->input('start', $request->input('start', 0)))
                ->take(request()->input('length', $request->input('length', -1)))
                ->toArray();

            $json['recordsFiltered'] = $query->count();

            return response()->json($json);
        } else {
            return view('tickets.index', ['title' => 'Tickets List']);
        }
    }

อธิบาย

  • บรรทัดที่ 4 เลือก function ที่ผูกกับ route ที่ต้องการ อย่าง index
  • บรรทัดที่ 6 คือ จะแยก URL เดียวกัน ถ้าเข้ามาโดยใช้ AJAX หรือ เปิดหน้าเว็บธรรมดา
    • มาจาก AJAX ก็จะส่งกลับเป็น JSON
    • มาจาก browser ก็ส่ง view ที่มี Datatable ไป
  • บรรทัดที่ 17 เป็นการเพิ่ม filter query เพิ่มตามเงื่อนไข
  • บรรทัดที่ 41 ตรงนี้จะเป็นการเพิ่ม column และมีการ map relational table เข้ามาจาก ตารางอื่น ๆ

อาจจะดูว่ามันซับซ้อน แต่วิธีนี้ มันควบคุมง่ายกว่า การใช้ library สำเร็จรูป และดูจาก sql query แล้ว มันมีประสิทธิ์ภาพมากกว่า