Sosa
Sosa

Reputation: 834

Laravel passing variables from one seed file to another?

I have created multiple seed files and my main DatabaseSeeder file looks like this:

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $name1 = "James";
        $name2 = "Jeff";
        $name3 = "Joe";

        $this->call(UserTableSeeder::class);
        $this->call(PersonTableSeeder::class);
        $this->call(IndividualTableSeeder::class);
        $this->call(HumanTableSeeder::class);
    }
}

How can I make it so that UserTableSeeder and PersonTableSeeder gets the variables from my main seeder file? (What I'm really trying to do is use Faker to output random values, but use the same value for each table seeder)

Upvotes: 13

Views: 10355

Answers (4)

Laravel 8,X

Here is a combination of all the best answers on that subject were I a prompt to get the values:


// DatabaseSeeder.php


    public function run() {
        // example 1: Use directly with inside seeder
        $name     = $this->command->ask( 'Name of first user', 'Jhon Doe' );
        $email    = $this->command->ask( 'Email of first user', '[email protected]' );
        $password = $this->command->ask( 'Password of  first user', '12345678' );

        User::factory()->create( [
            'name'     => $name,
            'email'    => $email,
            'password' => Hash::make( $password )
        ] );

        // example 2: Pass value to inner-Seeder
        $answer = $this->command->ask( "Do you want to make this user ($name:$email) an admin? (yes/no)", 'Yes' );
        $this->callWith( PermissionSeeder::class, [ 'answer' => $answer ] );
    }

// PermissionSeeder.php

 public function run( int|string $answer = null ) {
       // ...
        
        $rootID = null;

        if ( isset( $answer ) && ! empty( $answer ) ) {
            if ( is_numeric( $answer ) ) {
                $rootID = (int) $answer;
            } elseif ( is_string( $answer ) && str_starts_with( strtolower( $answer ), 'y' ) ) {
                $rootID = 1;
            }
        }

        echo $rootID ? "User [$rootID] will be elevated to super user" : "[$answer] Ignore  set-user-as-root.";
        echo "";
        if ( $rootID ) {
            $user = User::findOrFail( $rootID );
            $user?->assignRole( 'super-utilisateur' );
        }
}

Upvotes: 1

Tofandel
Tofandel

Reputation: 3565

As of laravel 8.2 you can pass parameters to seeders natively like so

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $name1 = "James";

        $this->callWith(UserTableSeeder::class, ['name' => $name1]);
        $this->call(PersonTableSeeder::class);
        $this->call(IndividualTableSeeder::class);
        $this->call(HumanTableSeeder::class);
    }

}

class UserTableSeeder extends Seeder {
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run($name = null)
    {
        var_dump($name);
    }
}

Upvotes: 9

chojnicki
chojnicki

Reputation: 3614

Anyone who is also looking for this. Accepted answer will work, but why over complicate such simple things?

Just use constants or globals.

DatabaseSeeder.php

define('SEEDING_SIZE', 10);

Now in any seeder this will be available as "SEEDING_SIZE".

No extra functions needed.

https://www.php.net/manual/en/function.constant.php

Upvotes: -3

Or Bachar
Or Bachar

Reputation: 1541

I had the same problem, ended up overriding the call() function by adding $extra var and passing it to run() function.

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $name1 = "James";
        $name2 = "Jeff";
        $name3 = "Joe";

        $this->call(UserTableSeeder::class, $name1);
        $this->call(PersonTableSeeder::class);
        $this->call(IndividualTableSeeder::class);
        $this->call(HumanTableSeeder::class);
    }

    public function call($class, $extra = null) {
        $this->resolve($class)->run($extra);

        if (isset($this->command)) {
            $this->command->getOutput()->writeln("<info>Seeded:</info> $class");
        }
    }

}

and then add $extra to your seeder class

// database/seeds/UserTableSeeder.php


  /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run($extra = null)
    {
        var_dump($extra);
    }

hope it helps.

Upvotes: 25

Related Questions