8 Tricks with Laravel Timestamps

Tutorial last revisioned on August 10, 2022 with Laravel 9

By default, Laravel Eloquent models assume your table has timestamp fields - created_at and updated_at. But there's plenty of things you can do to customize them or perform some interesting operations. Let's take a look.


1.Disable Timestamps

If your DB table doesn't have those fields, and you will try to do something like Model::create($arrayOfValues); - you will get SQL error. Laravel would try to automatically fill in created_at/updated_at and wouldn't find them.

To disable that automatic timestamps, in your Eloquent Model you need to add one property:

class Role extends Model
{
    public $timestamps = FALSE;

    // ... other model properties and methods
}

2. Change Timestamp Column Names

What if you're working with non-Laravel database and your timestamp columns are named differently? Maybe, you have create_time and update_time. Luckily, you can specify them in the model, too:

class Role extends Model
{
    const CREATED_AT = 'create_time';
    const UPDATED_AT = 'update_time';

3. Change Timestamp Date/Time Format

Here, I will just quote official Laravel documentation:

Before Laravel 7, dates would be serialized to a format like the following: 2019-12-02 20:01:00. From Laravel 7, dates serialized using the new format will appear like: 2019-12-02T20:01:00.283041Z. If you need to customize the timestamp format, set the $dateFormat property on your model. This property determines how date attributes are stored in the database, as well as their format when the model is serialized to an array or JSON:

class Flight extends Model
{
    /**
     * The storage format of the model's date columns.
     *
     * @var string
     */
    protected $dateFormat = 'U';
}

4. Many-to-Many: Pivot Table with Timestamps

A bit of exception for timestamps automation is when you create a pivot table in many-to-many relationships, like table role_user between users and roles tables.

In the model, you would define relationship like this:

class User extends Model
{
    public function roles()
    {
        return $this->belongsToMany(Role::class);
    }
}

And then, when you want to add a role to a user, you would do something like this:

$roleID = 1;
$user->roles()->attach($roleID);

By default, those pivot tables don't contain timestamps. And Laravel doesn't try to fill in created_at/updated_at in this case.

But if you do want to save the timestamps automatically, you need to add them into migration file, and then define relationship using ->withTimestamps();

public function roles()
{
    return $this->belongsToMany(Role::class)->withTimestamps();
}

5. Order by Timestamp with latest() and oldest()

There are two "shortcuts" to order data by timestamps.

Instead of:

User::orderBy('created_at', 'desc')->get();

You can do it quicker:

User::latest()->get();

By default, latest() will order by created_at.

There is an opposite method oldest() which would order by created_at ascending.

User::oldest()->get();

Also, you can specify another column to order by. For example, if you want to use updated_at, you can do this:

$lastUpdatedUser = User::newest('updated_at')->first();

6. Update without touching updated_at

Whenever you update Eloquent record, it automatically saves current timestamp into updated_at column, and that's a great feature.

But sometimes you want to avoid it, like you increment some value and don't want to consider it as "full record update".

Then, you need to do the same as above - disable timestamps, but only for that one time:

$user = User::find(1);
$user->profile_views_count = 123;
$user->timestamps = false;
$user->save();

7. Touch and Parent Touch

Opposite of the last example - maybe you want to set new value to ONLY updated_at column, and not change others.

So, instead of:

$user->update(['updated_at' => now()]);

You can use a shorter method:

$user->touch();

Another case - sometimes you want to not only set updated_at of current Eloquent model, but also it's parent record by relationship.

For example, if some comment was updated, then you want to consider that post record should have new updated_at, too.

Then, you need to define "parent touches" models in the Eloquent model:

class Comment extends Model {

    protected $touches = ['post'];

    public function post()
    {
        return $this->belongsTo(Post::class);
    }

}

8. Timestamp Fields are Carbon Automatically

Last "bonus" tip - more like a "reminder" because you should know about it.

By default, both created_at and updated_at are casts as $dates of Eloquent model, so you can perform Carbon operations on them, without converting to Carbon instance.

For example:

$user->created_at->addDays(3);
now()->diffInDays($user->updated_at);

That's it, quick but hopefully useful tips!

No comments or questions yet...

Like our articles?

Become a Premium Member for $129/year or $29/month
What else you will get:
  • 22 courses (477 lessons, total 38 h 20 min)
  • 2 long-form tutorials (one new every week)
  • access to project repositories
  • access to private Discord