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!