Modify Laravel model values in a mutator

written at: 2024-08-01

When i used the option to cast properties in a Laravel model, i assumed it worked everywhere. This assumption was only right in the case of a serialized model (converted to array), so upon trying to do an implementation it did not work out of the box as i expected. I seem to remember it working (for example in a blade template), but maybe my memory is making a mistake. It happens..

It appears castable properties work after serializing the model. So basically, it works when being converted to an array. This happens when using the model as a API resource (among other things).

If you like to change or modify a property, mutators are the way to go in these cases. When creating a mutator, the name usually starts with the column name in camelcase. So imagine a columname like 'building_year' will be converted to buildingYear. You'll write the mutator in the model you'd like to use it in, as follows:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Support\Carbon;

class Premise extends Model
{
    protected function buildingYear(): Attribute
    {
        return Attribute::make(
            get: fn ($value) => Carbon::parse($value)->format('Y-m-d')
        );
    }
}

The above function will take the value of the column, in this case a date and format it in the way you want. Please note that it will not change anything in your database, but merely the way it is formatted/changed or whatever.

You can use the new formatted date by either using the camelcase name, or the regular column name. Another usecase could be number formatting, currency formatting or maybe prefixing some text. The possibilities are up to you.

If you want to read more about mutators (and other useful information), read here: Laravel Accessors and Mutators

Thanks for reading, i hope it was of use!