ERaufi
ERaufi

Reputation: 1663

Laravel Activity Log won't work on Update and Delete

I'm using SPATIE laravel-activitylog I followed all the instructions but still, it only logs the Create function not update and delete while using it on a Modal

My Modal

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\Traits\LogsActivity;

class z_education extends Model
{
    //
    use LogsActivity;

    protected $fillable = [
        'user_id',
        'type',
        'school_name',
        'degree',
        'isremoved',
    ];
    protected static $logFillable = true;

}

My Controller

    public function delete_user_education($id)
    {
        z_education::where('id', $id)->delete();
        return back();
    }

Upvotes: 2

Views: 3654

Answers (2)

Abdo-Host
Abdo-Host

Reputation: 4103

To save log activity when performing update or delete operations in Laravel using Eloquent, you can utilize Eloquent events such as updating and deleting. These events allow you to intercept the model's lifecycle and log the activity before the operation is executed.

Example Implementation Create a Log Model (if not already created): Create a model and migration for logging activities.

php artisan make:model ActivityLog -m

Update the migration file to include the necessary fields, such as action, model_type, model_id, changes, and performed_by.

public function up() {
    Schema::create('activity_logs', function (Blueprint $table) {
        $table->id();
        $table->string('action');
        $table->string('model_type');
        $table->unsignedBigInteger('model_id');
        $table->json('changes')->nullable();
        $table->unsignedBigInteger('performed_by')->nullable(); // Nullable for system actions
        $table->timestamps();
    });
}

Run the migration:

php artisan migrate

Set Up the Eloquent Events: In the Eloquent model where you want to track updates and deletes, use the boot method to define updating and deleting event handlers.

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Models\ActivityLog;
use Illuminate\Support\Facades\Auth;

class YourModel extends Model {
    protected static function boot() {
        parent::boot();

        static::updating(function ($model) {
            ActivityLog::create([
                'action' => 'updated',
                'model_type' => get_class($model),
                'model_id' => $model->id,
                'changes' => json_encode([
                    'old' => $model->getOriginal(),
                    'new' => $model->getDirty(),
                ]),
                'performed_by' => Auth::id(),
            ]);
        });

        static::deleting(function ($model) {
            ActivityLog::create([
                'action' => 'deleted',
                'model_type' => get_class($model),
                'model_id' => $model->id,
                'changes' => json_encode([
                    'deleted' => $model->toArray(),
                ]),
                'performed_by' => Auth::id(),
            ]);
        });
    }
}

Optional: Create a Helper Trait: If you need this functionality across multiple models, create a reusable trait.

namespace App\Traits;

use App\Models\ActivityLog;
use Illuminate\Support\Facades\Auth;

trait LogsActivity {
    protected static function bootLogsActivity() {
        static::updating(function ($model) {
            ActivityLog::create([
                'action' => 'updated',
                'model_type' => get_class($model),
                'model_id' => $model->id,
                'changes' => json_encode([
                    'old' => $model->getOriginal(),
                    'new' => $model->getDirty(),
                ]),
                'performed_by' => Auth::id(),
            ]);
        });

        static::deleting(function ($model) {
            ActivityLog::create([
                'action' => 'deleted',
                'model_type' => get_class($model),
                'model_id' => $model->id,
                'changes' => json_encode([
                    'deleted' => $model->toArray(),
                ]),
                'performed_by' => Auth::id(),
            ]);
        });
    }
}

Use the trait in your models:

namespace App\Models;

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

class YourModel extends Model {
    use LogsActivity;
}

Display Logs (Optional): You can now query the activity_logs table to retrieve the logs for a specific model.

$logs = ActivityLog::where('model_type', YourModel::class)->get();

Upvotes: 0

Aken Roberts
Aken Roberts

Reputation: 13447

Your controller query is executed via the Query Builder, instead of an Eloquent Model. So there will be no model events to listen to.

Retrieve and delete the model itself to fire and log the events:

$model = z_education::findOrFail($id);
$model->delete();

return back();

Upvotes: 3

Related Questions