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!

avatar

Hello

How to add disable button with time stamp (same as soft delete).

When item/product/service is disabled, it show up in list as disabled (grey out), this cannot be selected for new transaction, it is listed in disable state due to related transactions/records.

Thank You Sudheer

avatar

Hi, not sure what exactly you have in mind here. Where do you need to disable it? On the select list?

avatar

Sorry, have difficulty in explaining.

Using Asset Management as example, Add Written off button.

Asset which was allocated before cannot be deleted to maintain past records for audit purpose. Only Unallocated Asset can be deleted (for example add by mistake). Written off Assets is visible in show blade for records purpose only, written off assets not availble in dropdown list (cannot be selected).

How to add written off button, How to select Asstes which are not written off (same as not soft deleted).

Field Type Database Column Visual Title auto_increment id ID belongsToRelationship category Category text serial_number Serial Number text name Name belongsToRelationship status Status belongsToRelationship location Location textarea notes Notes belongsToRelationship assigned_to Assigned to

datetime writtenoff_at Written off datetime created_at Created at datetime updated_at Updated At datetime deleted_at Deleted At

avatar

In that case you need to modify the select query by adding a condition to filter out written off assets.

Should be as simple as:

Model::whereNull('wrottenoff_at')->....

Like our articles?

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

Recent New Courses