Skip to content

Conversation

@nunomaduro
Copy link
Member

@nunomaduro nunomaduro commented Dec 7, 2021

This pull request proposes a creation of a public trait — WithoutModelEvents — that prevents Model Events from being executed while running seeds.

Laravel developers often use Model events for firing queueable or not queueable tasks, that will send emails, index their Laravel Scout data, logging, etc. And, while useful, I don't necessarily want these tasks to be executed by my seeders.

So, having this WithoutModelEvents trait, which is very similar to the testing trait WithoutModelEvents, it's super useful, especially when using Factories on my seeds:

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;

class DatabaseSeeder extends Seeder
{
    use WithoutModelEvents;

    public function run()
    {
        // these models are created, but no Model Events are
        // fired thanks to the `WithoutModelEvents` trait...
        User::factory(10)->create(); 
    }
}

Regarding the implementation there are two things to keep in mind:

  • First, we are only disabling Model Events, and not events in general.
  • Second, when using the method $this->call to call multiple seeders, the WithoutModelEvents propagates down. Let's see two examples:
  1. In this example, the DatabaseSeeder is called, and because it contains the WithoutModelEvents trait, no Models Events are ever fired when using this seeder:
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;

class DatabaseSeeder extends Seeder
{
    use WithoutModelEvents;

    public function run()
    {
        User::factory(10)->create(); // no Model Events are fired... 🔇

        $this->call([
            UserSeeder::class, // no Model Events are fired... 🔇
            UserWithoutModelEventsSeeder::class, // no Model Events are fired... 🔇
        ]);
    }
}
  1. In this example, the DatabaseSeeder is called, and it do not contain the WithoutModelEvents trait, so Model Events get fired by the UserSeeder::class but not by UserWithoutModelEventsSeeder::class:
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        User::factory(10)->create(); // Model Events are fired... 🔈✅

        $this->call([
            UserSeeder::class, // Model Events are fired... 🔈✅
            UserWithoutModelEventsSeeder::class,  // no Model Events are fired... 🔇
        ]);
    }
}

@nunomaduro nunomaduro changed the title [9.x] Adds WithoutEvents trait for running seeds without Model Events [9.x] Adds WithoutModelEvents trait for running seeds without Model Events Dec 7, 2021
Co-authored-by: James Brooks <[email protected]>
@jbrooksuk jbrooksuk self-requested a review December 7, 2021 20:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants