Hướng dẫn dùng laravel filter trong PHP

Trong một dự án thực tế việc chúng ta phải query filter cho các phần search data cho một website là một chức năng thông thường. Vậy làm sao để xây dựng filter một cách hiệu quả dễ mở rộng, thay đổi, tái sử dụng. Trong bài viết này mình sẽ hướng dẫn các bạn query filter trong laravel và nó không thật sự quá khó đâu.

1. Cách làm thông thường

public function index[Request $request]
{
    $user = User::query[];

    if [$request->has['name']] {
        $user->where['name', 'LIKE', '%' . $request->name . '%'];
    }
    if [$request->has['status']] {
        $user->where['status', $request->status];
    }
    if [$request->has['birthday']] {
        $user->whereDate['birthday', $request->birthday];
    }

    return $user->get[];
}

Đây là cách chúng ta thường hay sử dụng, rất dễ viết tuy nhiên có một nhược điểm là sẽ khó kiểm soát nếu cần search nhiều field, phải lặp đi lặp lại điều kiện if nhiều lần và không tái sử dụng được. Ở bài viết trước mình có giới thiệu về scope, nó có thể được sử dụng để giải quyết vấn đề không tái sử dụng được. Cách viết sẽ như thế này:

public function scopeName[$query, $request]
{
    if [$request->has['name']] {
        $query->where['name', 'LIKE', '%' . $request->name . '%'];
    }

    return $query;
}

public function scopeStatus[$query, $request]
{
    if [$request->has['status']] {
        $query->where['status', $request->status];
    }

    return $query;
}

public function scopeBirthday[$query, $request]
{
    if [$request->has['birthday']] {
        $query->whereDate['birthday', $request->birthday];
    }

    return $query;
}

Sau đó chúng ta sẽ gọi như sau:

public function index[Request $request]
{
    $user = User::query[]
        ->name[$request]
        ->status[$request]
        ->birthday[$request];

    return $user->get[];
}

Nhìn nó sẽ clear hơn, và chúng ta có thể sử dụng lại được ở những trường hợp khác khi cần filter theo 1 field nào đó.

2. Xây dựng class filter

Để tránh việc mỗi lần cần filter thêm một trường ta lại phải thêm một scope function trong model. Ta sẽ đi xây dựng một hàm filter, ý tưởng ở đây sẽ như thế này:

public function index[Request $request]
{
    $user = User::filter[$request];

    return $user->get[];
}

Hàm filter không nên khai báo nhiều lần, nó chỉ là hàm "trung chuyển" gọi các hàm filter của mỗi model. Ta sẽ triển khai nó bằng trait để các model có thể dùng chung. Tôi sẽ tạo một trait Filterable:

Chủ Đề