• Reading time ~ 1 min
  • 25.11.2023

If you have Watcher events to update or delete records, it's important to know that they only run when individual records are updated, not when they are updated in

bulk.Observer Code:This Observer is registered with the Service Provider:Now imagine three different Eloquent queries:

app/Observers/PostObserver.php:

class PostObserver{    public function deleted(Post $post)    {        // Например, удаляет связанные файлы изображений    }}

app/Providers/AppServiceProvider.php:

use App\Models\Post;use App\Observers\PostObserver;class AppServiceProvider extends ServiceProvider{    public function boot()    {        Post::observe(PostObserver::class);    }}

$post = Post::first();$post->delete();// Это БУДЕТ запускать НаблюдателяPost::find(2)->delete();// Это также БУДЕТ запускать НаблюдателяPost::where('id', '>', 3)->delete();// Но это НЕ БУДЕТ запускать Наблюдателя!$user->posts()->delete();// Это также НЕ БУДЕТ запускать Наблюдателя!

The reason is that the Observer events originate from the Eloquent Model. In the case delete() of Query Builder, the query is executed directly to the database, bypassing the individual model and its events.

Even if the result of the query is a single Eloquent model, Watchers will not run.

Post::where('id', 4)->delete();

This is true for any Observer method: updated() either updating(), delete() or deleting().

This is just as important in the case of some packets that automatically register Observers.

For example, in the case of Spatie Media Library, it registers a method deleted()that will not delete the associated media files if you delete Model entries in bulk instead of a single Model.

laravel-medialibrary/src/InteractsWithMedia.php:

trait InteractsWithMedia{    public static function bootInteractsWithMedia()    {        static::deleting(function (HasMedia $model) {            if ($model->shouldDeletePreservingMedia()) {                return;            }            if (in_array(SoftDeletes::class, class_uses_recursive($model))) {                if (! $model->forceDeleting) {                    return;                }            }            $model->media()->cursor()->each(fn (Media $media) => $media->delete());        });    }

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

ABOUT

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

About author CrazyBoy49z
WORK EXPERIENCE
Contact
Ukraine, Lutsk
+380979856297