Tutorial Laravel #24: Accessor, Mutator, dan Casts

1. Apa itu Accessor, Mutator, dan Casts?

Ketiganya adalah cara untuk memanipulasi data model secara otomatis:

  • Accessor - modifikasi nilai saat data dibaca dari model
  • Mutator - modifikasi nilai saat data disimpan ke model
  • Casts - konversi tipe data otomatis saat baca/tulis

2. Accessor (Baca Data yang Dimodifikasi)

<?php
namespace AppModels;

use IlluminateDatabaseEloquentModel;
use IlluminateDatabaseEloquentCastsAttribute;

class User extends Model
{
    // Accessor: nama selalu dalam format Title Case
    protected function name(): Attribute
    {
        return Attribute::make(
            get: fn (string $value) => ucwords(strtolower($value)),
        );
    }

    // Accessor virtual (tidak ada di database)
    protected function namaLengkap(): Attribute
    {
        return Attribute::make(
            get: fn () => $this->first_name . ' ' . $this->last_name,
        );
    }

    // Accessor: format harga dengan pemisah ribuan
    protected function harga(): Attribute
    {
        return Attribute::make(
            get: fn (int $value) => 'Rp ' . number_format($value, 0, ',', '.'),
        );
    }
}

$user = User::find(1);
echo $user->name;           // "ariq maulana" jadi "Ariq Maulana"
echo $user->nama_lengkap;   // "Ariq Maulana" (snake_case otomatis)
echo $user->harga;          // "Rp 150.000"

3. Mutator (Modifikasi Sebelum Disimpan)

class User extends Model
{
    // Mutator: password otomatis di-hash sebelum disimpan
    protected function password(): Attribute
    {
        return Attribute::make(
            set: fn (string $value) => bcrypt($value),
        );
    }

    // Accessor + Mutator sekaligus
    protected function name(): Attribute
    {
        return Attribute::make(
            get: fn ($value) => ucwords($value),
            set: fn ($value) => strtolower($value),
        );
    }
}

$user = new User();
$user->password = 'secret123';  // otomatis di-hash
$user->name = 'ARIQ MAULANA';   // disimpan sebagai "ariq maulana"
$user->save();

echo $user->name;               // dibaca sebagai "Ariq Maulana"

4. Casts - Konversi Tipe Otomatis

class Artikel extends Model
{
    protected $casts = [
        // Tanggal
        'published_at'   => 'datetime',
        'created_at'     => 'datetime:d M Y',  // format kustom

        // Tipe dasar
        'views'          => 'integer',
        'is_featured'    => 'boolean',
        'rating'         => 'float',

        // JSON - otomatis encode/decode
        'meta'           => 'array',
        'settings'       => 'collection',  // jadi Laravel Collection

        // Enum (PHP 8.1+)
        'status'         => StatusEnum::class,
    ];
}

$artikel = Artikel::find(1);
echo $artikel->published_at->format('d M Y');  // Carbon date otomatis
echo $artikel->is_featured ? 'Featured' : 'Biasa';  // boolean
$meta = $artikel->meta;     // sudah jadi array, tidak perlu json_decode

5. Custom Cast

<?php
// app/Casts/RupiahCast.php
namespace AppCasts;

use IlluminateContractsDatabaseEloquentCastsAttributes;

class RupiahCast implements CastsAttributes
{
    public function get($model, $key, $value, $attributes): string
    {
        return 'Rp ' . number_format($value, 0, ',', '.');
    }

    public function set($model, $key, $value, $attributes): int
    {
        // Hapus prefix Rp dan titik, kembalikan integer
        return (int) str_replace(['Rp ', '.', ','], '', $value);
    }
}

// Gunakan di model
protected $casts = [
    'harga' => RupiahCast::class,
];

6. Enum Cast (PHP 8.1+)

<?php
// app/Enums/StatusArtikel.php
namespace AppEnums;

enum StatusArtikel: string
{
    case Draft     = 'draft';
    case Published = 'published';
    case Archived  = 'archived';

    public function label(): string
    {
        return match($this) {
            self::Draft     => 'Draft',
            self::Published => 'Dipublish',
            self::Archived  => 'Diarsip',
        };
    }
}

// Di model
protected $casts = [
    'status' => StatusArtikel::class,
];

$artikel = Artikel::find(1);
echo $artikel->status->label();                 // "Draft"
echo $artikel->status === StatusArtikel::Draft; // true

7. Ringkasan

  • Accessor memodifikasi nilai saat dibaca dari model
  • Mutator memodifikasi nilai saat ditulis ke model
  • Casts mengkonversi tipe data otomatis - berguna untuk boolean, integer, datetime, array/JSON
  • Enum cast (PHP 8.1+) membuat status dan tipe data lebih type-safe

Tutorial berikutnya membahas service container dan dependency injection di Laravel.


ariq fadhil

Im Ariq Tech, a Top Rated Fullstack Developer with 5+ years of experience, delivering high-quality solutions across 50+ projects.