Laravel Tutorial

Bài 36: Eloquent ORM Serialize trong Laravel

Khi xây dựng các JSON API, bạn thường sẽ cần phải chuyển đổi các model và relationship của bạn thành array hoặc JSON. Eloquent có các phương thức tiện lợi cho việc thực hiện những chuyển đổi này, cũng như kiểm soát được các thuộc tính có trong serializations của bạn

1. Serialize to array

Để convert model data và các relationship của model đó (đã được load) sang aray các bạn chỉ cần sử dụng phương thức toArray. Phương thức này sẽ dùng đệ quy để convert tất cả dữ liệu về dạng array

use App\Models\User;

$user = User::with('roles')->first();
return $user->toArray();

Hoặc bạn cũng có thể sử dụng phương thức attributesToArray để chuyển đổi tất cả các attribute của model đó về dạng array

$user = User::first();
return $user->attributesToArray();

Hoặc bạn cũng có thể chuyển một collection model về dạng array bằng cách sử dụng phương thức toArray trong collection

$users = User::all();
return $users->toArray();
2. Serialize to Json

Để convert model data thành JSON, các bạn có thể sử dụng phương thức toJson. Cũng giống như phương thức toArray, phương thức toJson cũng sử dụng đệ quy để convert tất cả các attribute và relation đã được load trong model thành JSON

use App\Models\User;

$user = User::find(1);
return $user->toJson();

Bạn cũng có thể truyền vào phương thức toJson kiểu JSON endcod các bạn mong muốn (xem danh sách các kiểu JSON encode PHP hỗ trợ)

use App\Models\User;

$user = User::find(1);
return $user->toJson();
return $user->toJson(JSON_PRETTY_PRINT);

Hoặc bạn cũng có thể ép model sang kiểu string. Lúc này magic method __toString sẽ gọi phương thức toJson để đưa model về dạng json

return (string) User::find(1);

Cũng vì điều này nên các bạn có thể return luôn model data ở trong route, hoặc controller. Thì Laravel sẽ tự động convert model đó sang JSON

Route::get('users', function () {
    return User::all();
});

Chú ý: Đối với relation name của model khi được convert sang JSON thì key name sẽ tự động được convert sang dạng “snake_case“. Ví dụ relation name của bạn là “roleGroup” thì khi convert sang JSON nó sẽ có key là “role_group“.

Nếu như bạn muốn ẩn một số attribute ra khỏi JSON response. Bạn có thể config ở trong thuộc tính $hidden  của model

Ví dụ: Ẩn trường password khi convert JSON

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
    * The attributes that should be hidden for arrays.
    *
    * @var array
    */
    protected $hidden = ['password'];
}

Hoặc bạn cũng có thể config các trường sẽ được hiển thị khi convert sang JSON bằng cách thiết lập chúng trong thuộc tính $visible của model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
    * The attributes that should be hidden for arrays.
    *
    * @var array
    */
    protected $visible = ['first_name', 'last_name'];
}

Nếu như bạn không muốn thiết lập kiểu mặc định như trên, bạn có thể sử dụng phương thức makeVisible để hiển thị các trường đang được hidden của object hiện tại

return $user->makeVisible('remember_token')->toArray();

Và ngược lại, bạn cũng có thể ẩn các trường đang được visible trong model object hiện tại bằng cách sử dụng phương thức makeHidden

return $user->makeHidden('attribute')->toArray();

Nếu như bạn muốn đưa thêm một số attribute khác vào trong JSON data, bạn có thể định nghĩa ra một accessor và config attribute đó trong thuộc tính $append

Ví dụ: Đưa thêm trường “is_admin” vào trong JSON data

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
    * The accessors to append to the model's array form.
    *
    * @var array
    */
    protected $appends = ['is_admin'];
    /**
    * Determine if the user is an administrator.
    *
    * @return bool
    */
    public function getIsAdminAttribute()
    {
        return $this->attributes['admin'] === 'yes';
    }
}

Tương tự như visible và hidden, bạn cũng có thể append thêm data cho từng model object cụ thể bằng cách sử dụng phương thức append

return $user->append('is_admin')->toArray();

Hoặc bạn có thể sử dụng phương thức setAppends để thiết lập lại các giá trị đang được định nghĩa trong thuộc tính append của model

return $user->setAppends(['is_admin'])->toArray();
3. Serialize date

Mặc định các attribute có kiểu dữ liệu là date hoặc datetime trong model khi convert sang JSON sẽ được chuyển về dạng ISO 8601, nhưng nếu bạn không muốn điều đó. Bạn có thể định nghĩa format mà bạn muốn trong phương thức serializeDate của model

protected function serializeDate(DateTimeInterface $date)
{
    return $date->format('Y-m-d');
}

Hoặc bạn cũng có thể định nghĩa trong thuộc tinh $casts

protected $casts = [
    'birthday' => 'date:Y-m-d',
    'joined_at' => 'datetime:Y-m-d H:00',
];

 

Leave a Comment