Laravel: Save created_by, and updated_by User Information

Let’s store the information of the user, who has created or updated a model. Keeping this information is helpful for tracking the history of the model, and it can also be used to track the action history of the user.

NOTES

Here we are saving the created_by, and updated_by user information for a model.

We are using “Product” model for examples in this article. We are also assuming that the user information is saved in the “users” table.

The same process can be used to store deleted_by user. Just remember to enable soft delete for the model if you want deleted_by information.

The process is simple, and only 2 changes are required for this-

Step #1: Create Migration

First, we need to add the created_by and updated_by fields. So first create a migration for the product table to add fields-

php artisan make:migration add_created_updated_by_to_product
Bash

Here is the migration file-

In the up migration, add columns “created_by” and “updated_by“. Also, add foreign keys that refer to the “users” table.
In the down migration remove the foreign keys, and then drop the “created_by” and “updated_by” columns.
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::table('products', function (Blueprint $table) {
            $table->unsignedBigInteger('created_by')->nullable();
            $table->unsignedBigInteger('updated_by')->nullable();

            $table->foreign('created_by')->references('id')->on('users')->onDelete('set null');
            $table->foreign('updated_by')->references('id')->on('users')->onDelete('set null');
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::table('products', function (Blueprint $table) {
            $table->dropForeign(['created_by']);
            $table->dropForeign(['updated_by']);

            $table->dropColumn(['created_by', 'updated_by']);
        });
    }
};
PHP

Step #2: Save User Info

To save the information, on create and update, we can do it in 2 ways. Let’s check one by one-

Method #1: Save in Model

Create function “boot()” in the model. This registers model events.
Add an event for creating. Check the authentication and set “Auth::id()” as “created_by“.
Add an event for updating. Check the authentication and set “Auth::id()” as “updated_by“.
Create function “createdBy()” and “updatedBy()“, and establish the relation with the user model.

NOTES

The “boot()” method is automatically called when the model is initiated by Laravel.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\Auth;

class Product extends Model
{
    // Other model items here
    
    
    /**
     * Boot method for the Product model.
     */
    protected static function boot(): void
    {
        parent::boot();

        // Assign the `created_by` on creation
        static::creating(function (Model $model): void {
            if (Auth::check()) {
                $model->created_by = Auth::id();
            }
        });

        // Assign the `updated_by` on update
        static::updating(function (Model $model): void {
            if (Auth::check()) {
                $model->updated_by = Auth::id();
            }
        });
    }
    

    // Other functions here
    
    
    /**
     * Define the relationship with the creator (User model).
     *
     * @return BelongsTo
     */
    public function createdBy(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    /**
     * Define the relationship with the updater (User model).
     *
     * @return BelongsTo
     */
    public function updatedBy(): BelongsTo
    {
        return $this->belongsTo(User::class, 'updated_by');
    }
}
PHP

Method #2: Save using Trait [recommended]

Create trait “HasUserTracking“.
Create method “bootHasUserTracking“. This will register the events declared inside it.
Define “createdBy()” and “updatedBy()” to get the relevant user information.

NOTES

The “bootHasUserTracking()” method is automatically called when the model is initiated by Laravel.

If we use the naming format “boot<TRAIT_NAME>” for a function in a trait, and we use the trait in the Laravel model, it is automatically triggered during model initialization.

<?php

namespace App\Traits;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\Auth;

trait HasUserTracking
{
    /**
     * Boot the HasUserTracking trait to automatically set user tracking fields.
     *
     * @return void
     */
    public static function bootHasUserTracking(): void
    {
        static::creating(function (Model $model): void {
            if (Auth::check()) {
                $model->created_by = Auth::id();
            }
        });

        static::updating(function (Model $model): void {
            if (Auth::check()) {
                $model->updated_by = Auth::id();
            }
        });
    }

    /**
     * Define the relationship with the user who created the model.
     *
     * @return BelongsTo
     */
    public function createdBy(): BelongsTo
    {
        return $this->belongsTo(\App\Models\User::class, 'created_by');
    }

    /**
     * Define the relationship with the user who last updated the model.
     *
     * @return BelongsTo
     */
    public function updatedBy(): BelongsTo
    {
        return $this->belongsTo(\App\Models\User::class, 'updated_by');
    }
}
PHP

Then we can just add the “use HasUserTracking” in the model. This will enable the user tracking for the model.

<?php

namespace App\Models;

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

class Product extends Model
{
    use HasUserTracking;

    // other model code...
}
PHP

NOTES

Now we can just “user HasUserTracking” to any model and it will have the user tracking, if the “created_by” and “updated_by” columns are there in the table.

Leave a Comment


The reCAPTCHA verification period has expired. Please reload the page.