Laravel 8 — run seeder with parameters using artisan console

Paul Reaney
2 min readOct 13, 2020

I have a quiz app which has the standard questions and answers etc. For development, I’d like to be able to create new quizzes and seed my database with test data. I can do this by calling a seeder class:

php artisan db:seed --class=QuizSeeder

What if I want to create a quiz with a variable number of questions, answers and user responses? I could do this by passing an environment variable, but I want this to be more intuitive.

What if I create an artisan command to take in my arguments and pass them to my seeder? It sounded good to me in theory, so this is what I tried:

Make the seeder:

php artisan make:seeder QuizBuilderSeeder

This just makes a skeleton seeder class in /database/seeders/QuizBuilderSeeder.php

Make the command:

php artisan make:command  QuizBuilder --command=quiz:build

This makes a class at /app/Console/Commands/QuizBuilder.php. I put a description of what I was doing in the $description variable.

I can see the description show up when I run:

php artisan list//output

quiz:build Dynamic quiz builder

Now when I run:

php artisan quiz:build

This will run the handle method in Quizbuilder.php. All I need to do now is get my arguments as variables and pass them to my seeder.

How do I pass arguments?

In the $signature variable I can add parameters. In my case, I want to set default values if I don’t pass anything, so I did this for my number of questions and answers:

protected $signature = 'quiz:build {--Q|questions=100} {--A|answers=100}';

This means I can call the following commands:

php artisan quiz:build --questions=6 //6 questionsphp artisan quiz:build -Q 19 //19 questionsphp artisan quiz:build //100 questions (because the default is 100)

As you can see the parameters -Q and — questions are equivalent and optional.

Now in the handle function, we need to get the options for questions & answers, and run the seeder:

$seeder = new QuizBuilderSeeder();
$seeder->run($this->option('answers'), $this->option('questions'));

Now I can access these class-level variables in the seeder, and write my seeder using those parameters.

My final code from each class:

class QuizBuilder extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'quiz:build {--Q|questions=100} {--A|answers=100}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Dynamic quiz builder';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$seeder = new QuizBuilderSeeder;
$seeder->callWith(QuizBuilderSeeder::class, [$this->option('answers'), $this->option('questions')]);
return 0;
}
}
class QuizBuilderSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @param int $answers
* @param int $questions
* @return void
*/
public function run(int $answers, int $questions)
{
//do seeder stuff!
}
}

Thanks for reading!

--

--

Paul Reaney

I am a software developer and I like to write about interesting things I come across in my day to day.