Run Seeder Files from Different Sub Directories in Laravel
Programmers are required to tackle extensive projects and manage a multitude of seeder files. Keeping all seeders inside single folder sometimes become tough.
To solve this problem, a convenient solution involves categorizing seeders into distinct subdirectories according to modules or features or other requirements. This article aims to explain the approach to achieve this goal, providing clarity on the process.
Here is my laravel project’s screenshot after making sub-directories inside database/seeders directory.
Now it’s time to write some code inside database/seeders/DatabaseSeeder.php for reaching to our goal. First we will have to read all sub-directories located inside database/seeders . After that we will load all seeder files under those sub directories.
Read all subdirectories using recursive getAllSubdirectoriesOptimized() method.
/**
* Get All Seeders SUb Directory
* @param string $dir
* @return array
*/
private function getAllSubdirectoriesOptimized(string $dir): array
{
$subdirectories = [];
$items = scandir($dir);
foreach ($items as $item) {
if ($item !== '.' && $item !== '..') {
$path = $dir . DIRECTORY_SEPARATOR . $item;
if (is_dir($path)) {
$subdirectories[] = $path;
$subdirectoriesToAdd = $this->getAllSubdirectoriesOptimized($path);
foreach ($subdirectoriesToAdd as $subdirToAdd) {
$subdirToAdd = str_replace(database_path('seeders'), '', $subdirToAdd);
$subdirToAdd = ltrim($subdirToAdd, '\\');
$subdirectories[] = $subdirToAdd;
}
}
}
}
return $subdirectories;
}
This will load all sub-directories like below
[0] => D:\laragon\www\l10test\database\seeders\Common
[1] => Common\Module
[2] => Common\Module\Submodule
[3] => Common\Module\Submodule2
[4] => Common\Module\Submodule3
[5] => Common\Module\Submodule4
We will also create another method called loadSeedersFromSubdirectory() to load all seeder files from all sub-directories.
/**
* @param $subdirectory
* @return void
*/
protected function loadSeedersFromSubdirectory($subdirectory)
{
$seederPath = database_path('seeders/' . $subdirectory);
if (!is_dir($seederPath)) {
return;
}
$files = scandir($seederPath);
foreach ($files as $file) {
if (Str::endsWith($file, '.php')) {
$seederClass = 'Database\\Seeders\\' . $subdirectory . '\\' . Str::replaceLast('.php', '', $file);
$this->call($seederClass);
}
}
}
loadSeedersFromSubdirectory() method will load all seeders class from all sub directories
"Database\\Seeders\\Common\\Module\\PostsSeeder.php"
"Database\\Seeders\\Common\\Module\\Submodule\\ApprovalSeeder.php"
"Database\\Seeders\\Common\\Module\\Submodule3\\SpradicSeeder.php"
"Database\\Seeders\\Common\\Module\\Submodule4\\AbcdSeeder.php"
Now it’s time to call two methods inside database/seeders/DatabaseSeeder.php file
/**
* Seed the application's database.
*/
public function run(): void
{
$subdirectories = $this->getAllSubdirectoriesOptimized(database_path('seeders'));
foreach ($subdirectories as $subdirectory) {
$this->loadSeedersFromSubdirectory($subdirectory);
}
}
Finally our database/seeders/DatabaseSeeder.php will look like below
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*/
public function run(): void
{
$subdirectories = $this->getAllSubdirectoriesOptimized(database_path('seeders'));
foreach ($subdirectories as $subdirectory) {
$this->loadSeedersFromSubdirectory($subdirectory);
}
}
/**
* @param $subdirectory
* @return void
*/
protected function loadSeedersFromSubdirectory($subdirectory)
{
$seederPath = database_path('seeders/' . $subdirectory);
if (!is_dir($seederPath)) {
return;
}
$files = scandir($seederPath);
foreach ($files as $file) {
if (Str::endsWith($file, '.php')) {
$seederClass = 'Database\\Seeders\\' . $subdirectory . '\\' . Str::replaceLast('.php', '', $file);
$this->call($seederClass);
}
}
}
/**
* Get All Seeders SUb Directory
* @param string $dir
* @return array
*/
private function getAllSubdirectoriesOptimized(string $dir): array
{
$subdirectories = [];
$items = scandir($dir);
foreach ($items as $item) {
if ($item !== '.' && $item !== '..') {
$path = $dir . DIRECTORY_SEPARATOR . $item;
if (is_dir($path)) {
$subdirectories[] = $path;
$subdirectoriesToAdd = $this->getAllSubdirectoriesOptimized($path);
foreach ($subdirectoriesToAdd as $subdirToAdd) {
$subdirToAdd = str_replace(database_path('seeders'), '', $subdirToAdd);
$subdirToAdd = ltrim($subdirToAdd, '\\');
$subdirectories[] = $subdirToAdd;
}
}
}
}
return $subdirectories;
}
}
Now run below artisan command to run execute all seeders
php artisan db:seed
Output will be like below
Database\Seeders\Common\Module\PostsSeeder ............................................................................................... RUNNING
Database\Seeders\Common\Module\PostsSeeder ......................................................................................... 53.87 ms DONE
Database\Seeders\Common\Module\Submodule\ApprovalSeeder .................................................................................. RUNNING
Database\Seeders\Common\Module\Submodule\ApprovalSeeder ........................................................................... 656.09 ms DONE
Database\Seeders\Common\Module\Submodule3\SpradicSeeder .................................................................................. RUNNING
Database\Seeders\Common\Module\Submodule3\SpradicSeeder ............................................................................ 23.01 ms DONE
Database\Seeders\Common\Module\Submodule4\AbcdSeeder ..................................................................................... RUNNING
Database\Seeders\Common\Module\Submodule4\AbcdSeeder ............................................................................... 25.87 ms DONE
Hope that, this blog will help you to reduce your headache
I am regularly writing in this blog https://programmingmindset.com . You enhance your skill and by visiting this website