Automatically Update `created_by` and `updated_by` in Laravel Using Bootable Traits
Tags: laravel, eloquent, php, trait
Published: 2021-10-17 01:43:41

---
title: Automatically Update `created_by` and `updated_by` in Laravel Using Bootable Traits
published: true
description: Automatically Update `created_by` and `updated_by` in Laravel Using Bootable Traits
tags: laravel, Eloquent, PHP, Trait
cover_image: https://images.unsplash.com/photo-1599507593548-0187ac4043c6?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=3871&q=80
---

If you use `timestamps` feature in Laravel, then you got the free feature of auto-update on `created_at` and `update_at` columns when the model is created or updated. Now, what if you want the same thing for you own customs `created_by` and `updated_by` columns? You want them to be automatically updated with the logged in user's `id`. Well, you can use [observer](https://laravel.com/docs/8.x/eloquent#observers) or hook into model's lifecycle in `boot` or `booted` methods of the model. Let's use example of `Post` model as follows:

```php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{

    protected static function boot()
    {

        parent::boot();

        // updating created_by and updated_by when model is created
        static::creating(function ($model) {
            if (!$model->isDirty('created_by')) {
                $model->created_by = auth()->user()->id;
            }
            if (!$model->isDirty('updated_by')) {
                $model->updated_by = auth()->user()->id;
            }
        });

        // updating updated_by when model is updated
        static::updating(function ($model) {
            if (!$model->isDirty('updated_by')) {
                $model->updated_by = auth()->user()->id;
            }
        });
    }

}
```

In the above code, we hook into `creating` and `updating` lifecycle of the `Post` model. This works perfectly and is certainly convenient if you have only few models to apply this feature to. But what if you have many models? You have to apply the above code to all the models. Yes, it will work, but you know, it is not DRY. 

The bootable trait, which is also used by Laravel's [SoftDeletes](https://laravel.com/docs/8.x/eloquent#soft-deleting) trait, can save you a ton in this situation. Laravel' Eloquent model will boot a trait's method with the name of pattern `boot[TraitName]`. If you take a look into [Laravel's source code](https://github.com/laravel/framework/blob/8.x/src/Illuminate/Database/Eloquent/Model.php), you can find the snippet below.

```php
    /**
     * Bootstrap the model and its traits.
     *
     * @return void
     */
    protected static function boot()
    {
        static::bootTraits();
    }

    /**
     * Boot all of the bootable traits on the model.
     *
     * @return void
     */
    protected static function bootTraits()
    {
        $class = static::class;

        $booted = [];

        foreach (class_uses_recursive($class) as $trait) {
            $method = 'boot'.class_basename($trait);

            if (method_exists($class, $method) && ! in_array($method, $booted)) {
                forward_static_call([$class, $method]);

                $booted[] = $method;
            }

        }
    }
```

The above code tells us the trait with the name of `boot[traitName]` will also be invoked when the model is booted.

Knowing this, we now can create a new trait called `CreatedUpdatedBy` with a method of `bootCreatedUpdatedBy` as follows.

```php
<?php

namespace App\Traits;

trait CreatedUpdatedBy
{
    public static function bootCreatedUpdatedBy()
    {
        // updating created_by and updated_by when model is created
        static::creating(function ($model) {
            if (!$model->isDirty('created_by')) {
                $model->created_by = auth()->user()->id;
            }
            if (!$model->isDirty('updated_by')) {
                $model->updated_by = auth()->user()->id;
            }
        });

        // updating updated_by when model is updated
        static::updating(function ($model) {
            if (!$model->isDirty('updated_by')) {
                $model->updated_by = auth()->user()->id;
            }
        });
    }
}
```

Next, we can easily use it in any model that we want to apply it to just like when we use `SoftDeletes` trait. For example in our `Post` method, it should be looked like this.

```php
<?php

namespace App\Models;

use App\Traits\CreatedUpdatedBy;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use CreatedUpdatedBy;

}
```
Whenever the `Post` model is created or updated, the `created_by` and/or `updated_by` will be automatically updated. Cool! Isn't it? 😎 

Note that the above is just one example of using bootable traits in the Eloquent model to automatically update `created_by` and `updated_by`. However, there are many applications of it. For example, you can use it to automatically [delete related models](https://tighten.co/blog/laravel-tip-bootable-model-traits/), [update slugs](https://andy-carter.com/blog/using-laravel-s-eloquent-traits), and many others you can think of.