Query scopes trong Laravel là một tính năng mạnh mẽ cho phép bạn định nghĩa các phương thức trong model để tái sử dụng các truy vấn cơ sở dữ liệu một cách dễ dàng và hiệu quả. Thay vì phải lặp lại cùng một logic truy vấn trong nhiều nơi khác nhau trong mã nguồn của bạn, bạn có thể tạo ra các “scope” (phạm vi) để tổ chức và tái sử dụng chúng.

Tại sao sử dụng Query Scopes?

  1. Tái sử dụng mã: Giúp giảm thiểu mã lặp lại bằng cách tách riêng logic truy vấn vào trong các phương thức trong model.
  2. Cải thiện tính dễ đọc: Khi bạn sử dụng query scopes, mã của bạn trở nên dễ đọc hơn, dễ hiểu hơn, và dễ bảo trì hơn.
  3. Tổ chức tốt hơn: Các truy vấn có thể được tổ chức theo cách mà bạn có thể dễ dàng tìm thấy và sử dụng chúng.

Cách sử dụng Query Scopes

1. Định nghĩa Global Scopes

Global scopes được áp dụng cho tất cả các truy vấn trên model mà bạn định nghĩa. Bạn có thể sử dụng global scopes để tự động thêm các điều kiện vào mọi truy vấn.

Định nghĩa Global Scope

Để tạo một global scope, bạn cần tạo một class implement IlluminateDatabaseEloquentBuilderIlluminateDatabaseEloquentModel.

namespace AppModelsScopes;

use IlluminateDatabaseEloquentBuilder;
use IlluminateDatabaseEloquentModel;
use IlluminateDatabaseEloquentScope;

class ActiveScope implements Scope
{
    public function apply(Builder $builder, Model $model)
    {
        $builder->where('active', 1);
    }
}

Áp dụng Global Scope vào Model

Trong model của bạn, sử dụng phương thức booted để áp dụng scope.

namespace AppModels;

use AppModelsScopesActiveScope;
use IlluminateDatabaseEloquentModel;

class User extends Model
{
    protected static function booted()
    {
        static::addGlobalScope(new ActiveScope);
    }
}

Sử dụng

Khi bạn truy vấn User, global scope sẽ tự động được áp dụng.

$activeUsers = User::all(); // Chỉ lấy những người dùng có 'active' = 1

2. Định nghĩa Local Scopes

Local scopes là các phương thức riêng lẻ trong model mà bạn có thể sử dụng để thêm điều kiện vào truy vấn. Bạn có thể gọi local scope như một phương thức trên query builder.

Định nghĩa Local Scope

Trong model của bạn, định nghĩa một phương thức với tiền tố scope.

namespace AppModels;

use IlluminateDatabaseEloquentModel;

class User extends Model
{
    public function scopeActive($query)
    {
        return $query->where('active', 1);
    }

    public function scopeWithRole($query, $role)
    {
        return $query->where('role', $role);
    }
}

Sử dụng Local Scope

Khi bạn muốn sử dụng local scope, bạn có thể gọi nó như sau:

$activeUsers = User::active()->get(); // Lấy những người dùng có 'active' = 1

$adminUsers = User::withRole('admin')->get(); // Lấy những người dùng có 'role' = 'admin'

3. Kết hợp Local Scopes

Bạn có thể kết hợp nhiều local scopes để xây dựng các truy vấn phức tạp hơn.

$adminActiveUsers = User::active()->withRole('admin')->get(); // Lấy những người dùng có 'active' = 1 và 'role' = 'admin'

4. Sử dụng Parameters trong Local Scopes

Bạn có thể truyền tham số vào local scope để tăng cường tính linh hoạt.

public function scopeCreatedAfter($query, $date)
{
    return $query->where('created_at', '>', $date);
}

// Sử dụng
$recentUsers = User::createdAfter('2024-01-01')->get(); // Lấy những người dùng được tạo sau ngày 1 tháng 1 năm 2024

Kết luận

Query scopes trong Laravel là một cách hữu hiệu để tổ chức và tái sử dụng logic truy vấn trong ứng dụng của bạn. Bằng cách sử dụng global và local scopes, bạn có thể giảm thiểu mã lặp lại, cải thiện tính dễ đọc và dễ bảo trì của mã nguồn. Đây là một công cụ mạnh mẽ giúp bạn xây dựng các truy vấn phức tạp một cách dễ dàng và rõ ràng hơn. Hãy tận dụng query scopes để tối ưu hóa mã nguồn và nâng cao hiệu suất ứng dụng của bạn.