owen-it / laravel-auditing

Record the change log from models in Laravel
https://laravel-auditing.com
MIT License
2.94k stars 382 forks source link

Add `withoutAuditing()` callback method to temporarily disable auditing for one class #917

Closed derekmd closed 1 month ago

derekmd commented 3 months ago

Summary

Similar to Laravel's Model::withoutEvents() method, allow running Eloquent queries on a given model class inside a callback:

User::withoutAuditing(function () use ($user, $inputs, $additional) {
    // no audit
    $user->update($inputs);

    // this _will_ be audited if the Profile class is Auditable
    $user->profile()->updateOrCreate([], $additional);
});

Only the {class}::withoutAuditing() class will have auditing disabled, so additional model classes need their own call. e.g.,

User::withoutAuditing(fn () => $user->update($inputs));
Profile::withoutAuditing(fn () => $user->profile()->updateOrCreate([], $additional));

  1. It's wrapped in try / finally to handle restoring auditing after Eloquent possibly throws QueryException.
  2. If auditing is already disabled, that setting will be kept. i.e., don't call enableAuditing()

Links

derekmd commented 1 month ago

You can but that will also prevent other event listeners from being invoked. This method would allow only disabling audit callbacks.

anteriovieira commented 1 month ago

Could someone please update the documentation? You could follow the idea from the Laravel documentation.

https://laravel.com/docs/11.x/eloquent#muting-events

willpower232 commented 1 month ago

@derekmd would you like the honours? https://github.com/owen-it/laravel-auditing.com/ perhaps something under the advanced section?

derekmd commented 1 month ago

https://github.com/owen-it/laravel-auditing.com/pull/44

without-events-docs
erikn69 commented 1 month ago

@derekmd hi, this give me test errors: https://github.com/owen-it/laravel-auditing/actions/runs/9256833548

$result = Article::withoutAuditing(function () {
    $this->assertTrue(Article::$auditingDisabled);
    $this->assertFalse(ArticleExcludes::$auditingDisabled); //here, is true instead of false, why?
derekmd commented 1 month ago

@erikn69: https://github.com/owen-it/laravel-auditing/commit/a08c673e31bc4d55b6f5b5dd8cc9ab9085022d15#diff-a23c87e87a036f61cc6c88f12299ba20cfbbc59b4a825ee48689ee701aeace25L5 merged after I opened this PR changed test stub ArticleExcludes extends Article so the two classes now share the same static $auditingDisabled state.

erikn69 commented 1 month ago

Thanks, I already noticed it, #937

erikn69 commented 1 month ago

maybe another idea, globally disable audits on all models within the callback block, maybe it could be done with a second argument