Học Laravel – Bài 40: Eloquent: Mutators & Casting

Giới thiệu Mutators & Casting trong Eloquent:

Accessors (tiếp cận), mutators (biến đổi) và casting (ép kiểu) cho phép bạn chuyển đổi các thuộc tính (attribute) của Eloquent khi bạn truy xuất hoặc thiết lập (set) chúng trên model. Ví dụ bạn muốn dùng Laravel encrypter để mã hóa 1 giá trị trước khi lưu vào database, sau đó tự động giải mã khi truy xuất từ Eloquent model. Hoặc bạn có thể chuyển đổi 1 JSON trong database thành 1 array.

Accessors:

Tạo accessor:

1 accessor sẽ biến đổi giá trị của 1 attribute khi được tiếp cận. Để tạo accessor, tạo 1 protected method trong model tương ứng với attribute cần tiếp cận. Tên method tương ứng với cú pháp lạc đà của attribute. Ví dụ: tạo 1 accessor cho thuộc tính first_name. Accessor sẽ được tự động gọi bởi Eloquent khi truy xuất giá trị từ model. Các method của accessor đều return Illuminate\Database\Eloquent\Casts\Attribute:

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
    /**
     * Get the user's first name.
     */
    protected function firstName(): Attribute
    {
        return Attribute::make(
            get: fn (string $value) => ucfirst($value),
        );
    }
}

Tất cả method của accessor đều trả về 1 instance Attribute. Ở ví dụ này, ta mới chỉ định nghĩa cách attribute được tiếp cập. Để làm vậy, chúng ta cung cấp tham số get cho constructor (hàm khởi tạo) của Attribute.

Như bạn có thể thấy, giá trị nguyên thủy của column được pass cho accessor, cho phép bạn sử dụng và trả về giá trị. Để tiếp cận giá trị của accessor, bạn chỉ cần tiếp cận thuộc tính first_name trong model:

use App\Models\User;
 
$user = User::find(1);
 
$firstName = $user->first_name;

Build value object từ nhiều attribute:

Thi thoảng accessor cần chuyển đổi nhiều attribute thành 1 object. Để làm được, closure get cần thêm tham số thứ 2 $attributes, tham số này chứa array của toàn bộ attribute của model:

use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;
 
/**
 * Interact with the user's address.
 */
protected function address(): Attribute
{
    return Attribute::make(
        get: fn (mixed $value, array $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
    );
}

Accessor cache:

Khi trả về object từ accessor, bất kỳ thay đổi nào đến object sẽ được đồng bộ ngược lại model trước khi được lưu. Điều này khả thi vì Eloquent giữ lại instances được trả về bởi accessors vì vậy nó có thể trả về cùng instance mỗi lần accessor được gọi:

use App\Models\User;
 
$user = User::find(1);
 
$user->address->lineOne = 'Updated Address Line 1 Value';
$user->address->lineTwo = 'Updated Address Line 2 Value';
 
$user->save();

Tuy nhiên thi thoảng bạn cần bật cache cho các giá trị nguyên thủy như string, boolean. Để làm vậy, gọi method shouldCache khi define accessor:

protected function hash(): Attribute
{
    return Attribute::make(
        get: fn (string $value) => bcrypt(gzuncompress($value)),
    )->shouldCache();
}

Nếu bạn muốn disable

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *