Toidicode.com

Toidicode.com

BASIC TO ADVANCE

Bài 37: Mutator và Cast trong Laravel Eloquent

Tiếp tục với chuỗi bài về eloquent ORM trong Laravel, phần này mình sẽ giới thiệu với mọi người về mutator và cast trong Eloquent.

1. Giới thiệu.

Trong eloquent ORM, Laravel có cung cấp thêm các tính năng cho phép chúng ta thay đổi giá trị cả các attribute khi truy xuất đến cái này Laravel gọi là mutator và cast.

Những tính năng này sẽ rất hữu ích khi bạn muốn thực thi việc gì đó khi lưu trữ dữ liệu vào database. Ví dụ như mã hóa thông tin, convert data type,...

2. Mutator.

Accessor

Để định nghĩa một accessor trong eloquent model, bạn chỉ cần khai báo một phương thức nằm trong model chứa attribute mà bạn cần thay đổi giá trị có tên theo cú pháp:

get{Attribute}Attribute

Trong đó: {Attribute} là tên của thuộc tính bạn muốn thay đổi giá trị. Nếu thuộc tính được đặt theo dạng "snake_case" thì tên thuộc tính đó sẽ được convert về dạng "cameCase".

VD: Khai báo accessor cho thuộc tính "first_name".

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Get the user's first name.
     *
     * @param  string  $value
     * @return string
     */
    public function getFirstNameAttribute($value)
    {
        return ucfirst($value);
    }
}

Accessor trên có tác dụng in hoa chữ cái đầu tiên của first_name.

Lúc này các bạn có thể access đến attribute first_name trong model User để xem kết quả.

VD:

use App\Models\User;

$user = User::find(1);

$firstName = $user->first_name;

Và đương nhiên bạn có thể dùng accessor cho các attribute thực sự không tồn tại trong model.

VD: Thêm accessor lấy ra "full_name" của user.

/**
 * Get the user's full name.
 *
 * @return string
 */
public function getFullNameAttribute()
{
    return "{$this->first_name} {$this->last_name}";
}

Lúc này các bạn có thể truy vấn đến attribute full_name như một thuộc tính của model bình thường.

VD:

use App\Models\User;

$user = User::find(1);

$firstName = $user->full_name;

Mutator

Để khai báo một mutator trong eloquent model các bạn chỉ việc thay chữ get bằng set trong tên phương thức, còn lại cú pháp đặt tên thì giống như đối với accessor.

VD: Mình sẽ khai báo một mutator thay đổi giá trị của attribute first_name khi thực thi set giá trị cho nó.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Set the user's first name.
     *
     * @param  string  $value
     * @return void
     */
    public function setFirstNameAttribute($value)
    {
        $this->attributes['first_name'] = strtolower($value);
    }
}

Lúc này các bạn có thể set giá trị cho first_name của User để xem kết quả.

use App\Models\User;

$user = User::find(1);

$user->first_name = 'Sally';

echo $user->first_name // sally

3. Cast.

Cast trong eloquent thực ra cũng là các accesstor, mutator được định nghĩa sẵn trong eloquent ORM core. Cast đúng như tên gọi của nó, nó cho phép chúng ta chuyển đổi giá trị, ép kiểu dữ liệu của một attribute nào đó trong model.

Để khai báo cast trong model các bạn chỉ cần khai báo các attribute các bạn muốn cast và kiểu dữ liệu muốn cast thành vào trong thuộc tính $cast.

VD: Cast attribute blocked_at sang kiểu date.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

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

Lúc này các bạn có thể query thử và truy vấn đến thuộc tính blocked_at để kiểm tra.

Mặc định Laravel hỗ trợ sẵn cast các kiểu dữ liệu sau:

  • array
  • boolean
  • collection
  • date
  • datetime
  • decimal:<digits>
  • double
  • encrypted
  • encrypted:array
  • encrypted:collection
  • encrypted:object
  • float
  • integer
  • object
  • real
  • string
  • timestamp

Custom Cast

Tuy nhiên nếu các bạn muốn cast data sang một kiểu giá trị khác ngoài các kiểu hỗ trợ ở trên, các bạn có thể khai báo thêm các custom cast trong eloquent một cách rất đơn giản.

Để khai báo thêm một custom cast trong eloquent các bạn chỉ cần khai báo một class implement CastsAttributes (Illuminate\Contracts\Database\Eloquent\CastsAttributes) có chứa hai phương thức getset để thực hiện lấy ra và gán giá trị cho attribute.

VD: Mình sẽ khai báo thêm một cast để cast Json.

- app/Casts/Json.php

<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

class Json 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 json_decode($value, true);
    }

    /**
     * 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 json_encode($value);
    }
}

Lúc này nếu muốn sử dụng Json cast trong model bạn chỉ việc khai báo như sau:

<?php

namespace App\Models;

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

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

4. Lời kết.

Bài này mình chỉ giới thiệu với mọi người cơ bản về cast trong model thôi nếu các bạn cần tìm hiểu kĩ hơn có thể tham khảo tại link.

Đăng ký nhận tin.

Chúng tôi chỉ gửi tối đa 2 lần trên 1 tháng. Tuyên bố không spam mail!

Vũ Thanh Tài

About author
The best way to learn is to share
Xem tất cả bài đăng

1 Comments

Thanks

kl5mp

2 năm trước

Bình luận

Captcha