Elegant Eloquent Human Timestamps

Chris Di Carlo • October 18, 2020

Introduction

Recently I found myself needing to display humanized diffs for various timestamps, e.g. Edited 3 minutes ago. Having to add an accessor to my Laravel models for each property was getting a wee bit long in the tooth. I wanted something simple aka add a trait and be done with it. Hence I came up with this simple package to dynamically add an accessor based on the presence of a suffix.

Note There's other patterns you can use for this type of presentational formatting. This is an opinionated package - I'm perfectly cool with fat models for this use case.

A picture is worth a thousand words and in this case I think code works the same. Take this model:


<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Client extends Model { use HasFactory; protected $dates = [ last_logged_in, last_emailed, previous_appointment, ]; }

Ok, so a bit contrived but it's for demonstration purposes. Previously, I would need to add an accessor for each date property, like so:

public function getLastLoggedInForHumansAttribute() {
    return $this->last_logged_in ? $last_logged_in->diffForHumans() : null;
}

Rinse and repeat for each field you need. Yeah, that gets old quick.

Compare that to using this package:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use ChrisDiCarlo\EloquentHumanTimestamps\HumanTimestamps;

class Client extends Model
{
    use HasFactory;
    use HumanTimestamps;

    protected $dates = [
        last_logged_in,
        last_emailed,
        previous_appointment,
    ];
}

Now, whenever I want to display the human diff in my Blade templates, I can just use the property name and add "for_humans" to the end:

<div>{{ $client->last_logged_in_for_humans }}</div>

Voila! Instant human timestamps without the added tedium of the accessor creation.

It also works for the standard Laravel timestamp columns:

<div>{{ $updated_at_for_humans }}</div>

You can install the package through composer with:

composer require chrisdicarlo/eloquent-human-timestamps

Happy coding! Cheers!