Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[9.x] Adds WithoutModelEvents trait for running seeds without Model Events #39922

Merged
merged 3 commits into from
Dec 8, 2021

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.

4 participants