Trước đây, chúng ta bị giới hạn cast mặc định do Laravel cung cấp. Mặc dù, có một số gói thư viện có thể  giúp chúng ta custom được nhưng chúng có một nhược điểm lớn. Bởi vì, chúng ghi đề phương thức setAttribute và getAttribute thông qua trait, chúng không thể sử dụng bất kì một gói thư viện nào khác vì chúng cũng ghi đè phương thức đó.

Giờ đây, Laravel đã hỗ trợ phần custom cast, sẽ không xảy ra vấn đề như không tương thích giữa các thư viện nữa. Để hiểu rõ hơn về Laravel Custom Eloquent Casts chúng ta hãy thực hiện một số ví dụ đơn giản như sau.

Để khai báo một Custom Eloquent Casts:

Chúng ta cần implement interface CastsAttributes có chứa 2 phương thức get và set dùng để get giá trị và set giá trị cho các attribute.

Đầu tiên, chúng ta sẽ tạo một file tên là EncryptCast.php nằm ở thư mục app/Casts, phần tạo này các bạn hãy bằng tay vì Laravel chưa cung cấp lệnh command để tạo file một cách tự động.

Sau đó bạn hãy mở file EncryptCast.php và chỉnh sửa như sau:

<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

class EncryptCast implements CastsAttributes
{
    /**
     * Cast the given value.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  string  $key
     * @param  mixed  $value
     * @param  array  $attributes
     * @return array
     */
    public function get($model, $key, $value, $attributes)
    {
        return decrypt($value);
    }

    /**
     * Prepare the given value for storage.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  string  $key
     * @param  array  $value
     * @param  array  $attributes
     * @return string
     */
    public function set($model, $key, $value, $attributes)
    {
        return [$key => encrypt($value)];
    }
}

Trong Model (ở đây mình sử dụng Model User), chúng ta sẽ set thuộc tính password sử dụng Custom Cast mà chúng ta vừa tạo ở trên như sau:

<?php

namespace App\Models;

use App\Casts\EncryptCast;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The attributes that should be cast.
     *
     * @var array
     */
    protected $casts = [
        'password' => EncryptCast::class,
    ];
}

Bây giờ, chúng ta hãy trải nghiệm cách hoạt động của Laravel Custom Cast ở một controller bất kỳ nào.

/**
 * Show the form for creating a new resource.
 *
 * @return \Illuminate\Http\Response
 */
public function create()
{
    $user = User::first();
    $user->password = 'ManhDanBlogs';
    $user->save();      
    // Giá trị được mã hóa (sẽ được lưu vào database)
    // Raw value : eyJpdiI6IjI1dE9RMGFQUktjeTk5aTVIQWlSNX....
    dd($user->getAttributes()['password']);
    // Giá trị chưa được mã hóa
    dd($user->password);
}

Đôi khi, bạn chỉ muốn format giá trị đang set trên model và không thực hiện bất kỳ xử lý nào khi chúng ta truy xuất dữ liệu từ model.

Vì vậy, chúng ta nên sử dụng interface CastsInboundAttributes, vì nó chỉ yêu cầu bắt buộc duy nhất là hàm set.

Ví dụ, bạn muốn giới hạn độ dài của string khi thực hiện set giá trị trong model.

Đầu tiên, chúng ta sẽ tạo một file tên là LimitCaster.php nằm ở thư mục app/Casts và chỉnh sửa như sau:

<?php

namespace App\Casts;

use Illuminate\Support\Str;
use Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes;

class LimitCaster implements CastsInboundAttributes
{
     /**
     * Create a new cast class instance.
     *
     * @param  string|null  $algorithm
     * @return void
     */
    public function __construct($length = 25)
    {
        $this->length = $length;
    }

    /**
     * Prepare the given value for storage.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  string  $key
     * @param  array  $value
     * @param  array  $attributes
     * @return string
     */
    public function set($model, $key, $value, $attributes)
    {
        return [$key => Str::limit((string) $value, $this->length)];
    }
}

Trong Model (ở đây mình sử dụng Model User), chúng ta sẽ set thuộc tính name sử dụng Custom Cast mà chúng ta vừa tạo ở trên như sau:

<?php

namespace App\Models;

use App\Casts\LimitCaster;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The attributes that should be cast.
     *
     * @var array
     */
    protected $casts = [
       name' => LimitCaster::class . ':7'
    ];
}

Bây giờ, chúng ta hãy trải nghiệm cách hoạt động của nó ở một controller bất kỳ nào.

/**
 * Show the form for creating a new resource.
 *
 * @return \Illuminate\Http\Response
 */
public function create()
{
    $user = User::first();
    $user->name = 'ManhDanBlogs';
    $user->save();      
    // Value: ManhDan...
    dd($user->name);
}

Như vậy, chúng ta đã thực hiện xong một ví dụ đơn giản về Laravel Custom Cast, tôi hy vọng hướng dẫn của tôi sẽ giúp ích cho công việc của bạn. Nếu bạn có bất kỳ câu hỏi nào hãy liên hệ với chúng tôi qua trang contact. Cảm ơn bạn.

CÓ THỂ BẠN QUAN TÂM

Laravel Task Scheduling

Laravel Task Scheduling

Trong các ứng dụng lớn, bạn cần lên lịch định kì cho các công việc bằng Cron jobs.  Tại số một số thời điểm, việc quản lý các cron jobs trở nên cồng kềnh và khó khăn hơn. Laravel Scheduler là một côn...

Laravel Accessor and Mutator

Laravel Accessor and Mutator

Trong bài viết này, tôi sẽ hướng dẫn các bạn cách để format các Eloquent Attributes bằng cách sử dụng tính năng Laravel Accessors and Mutators. Accessors được sử dụng để format các thuộc tính khi c...

Laravel Migration

Laravel Migration

Migration cho phép các nhà phát triển (Developer) nhanh chóng tạo ra cở sở dữ liệu của ứng dụng mà không cần vào màn hình quản lý cơ sở dữ liệu hay chạy bất kì một câu lệnh SQL nào. Trước hết, nếu...

Fast Paginate in Laravel

Fast Paginate in Laravel

Laravel Fast Paginate là gì? Laravel Fast Paginate là một macro nhanh về phân trang offset/limit cho Laravel. Nó được sử dụng để thay thể paginate trong Laravel.Package này sử dụng phương pháp SQL t...

Method WhereAny / WhereAll  in Laravel Eloquent

Method WhereAny / WhereAll in Laravel Eloquent

New Laravel 10: Eloquent WhereAny() và WhereAll() Laravel cung cấp cho chúng ta khả năng xây dựng các truy vấn dữ liệu mạnh mẽ với Eloquent ORM, giúp chúng ta có thể xử lý các truy vấn cơ sở dữ li...

Laravel Socialite Login With Linkedin

Laravel Socialite Login With Linkedin

LinkedIn LinkedIn là mạng xã hội tập trung vào mạng lưới nghề nghiệp và phát triển nghề nghiệp và chuyên nghiệp lớn nhất thế giới trên internet. Bạn có thể sử dụng LinkedIn để tìm công việc hoặc...

Laravel Has Many Through Eloquent Relationship

Laravel Has Many Through Eloquent Relationship

Has Many Through Relationship hơi phức tạp để hiểu một cách đơn giản, nó sẽ cung cấp cho chúng ta một con đường tắt để có thể truy cập dữ liệu của một quan hệ xa xôi thông qua một mối quan hệ trung gi...

Laravel Many to Many Polymorphic Relationship

Laravel Many to Many Polymorphic Relationship

Many to many Polymorphic Relationship cũng hơi phức tạp để hiểu. Ví dụ: nếu bạn có bài post, video và tag, bạn cần kết nối với nhau theo yêu cầu là mọi bài đăng đều có nhiều tag và video cũng như vậy....

Export CSV from SQL Server - Import into MySQL with Laravel

Export CSV from SQL Server - Import into MySQL with Laravel

Transfer Database Trong quá trình phát triển và bảo trì dự án, việc di chuyển cơ sở dữ liệu từ hệ thống này sang hệ thống khác là một nhiệm vụ khá phổ biến. Giả sử bạn cần di chuyển dữ liệu từ SQ...

ManhDanBlogs