How to use Accessors and Mutators to Format Dates in Laravel

How to use Accessors and Mutators to Format Dates in Laravel

When we work with dates and datepickers we always encounter problems with the format because our database (MySql) expects Y-m-d format but in the frontend, we need something more readable like the mm/dd/yyyy format, but how we can solve this problem, for that we need the magic of accessor and mutators begins

What are Accessors and Mutators?

Accessors allow us to transform the attributes when coming from the database whereas Mutators let us transform the attributes before saving them in our database.

How to Define an Accessor and Mutator

To define an Accessor, we need to use the following syntax get{Attribute}Attribute where {Attribute} is the name of the field we want to access and Mutator can be define using set{Attribute}Attribute syntax.

Let's do an example, we have a model Product and we have a column expiration_date we need to create two new functions in our model.

<?php

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
        'expiration_date'
    ];

    public function setExpirationDateAttribute($value)
    {
        $this->attributes['expiration_date'] = Carbon::createFromFormat('m/d/Y', $value)->format('Y-m-d');
    }

    public function getExpirationDateAttribute($value)
    {
        return $value ? Carbon::parse($value)->format('m/d/Y') : null;
    }
}

Let me explain some things.

  • In this case, we use Carbon library to transform the dates in the format we want. Don't forget to import use Carbon\Carbon in the model.

  • The field expiration_date is in snake_case but when we use an Accessor or Mutator, change to camelCase.

  • Every time we need to access to Product::all() or Product::select('expiration_date')->get(), the date format wil be m/d/Y.

  • Every time we need to store a product with Product::create() automatically transform the expiration_date before saving the record.

Thanks for reading.