Run Seeder Files from Different Sub Directories in Laravel

Ariful Islam
3 min readOct 25, 2023

--

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.

Seeders and migrations folders are devided into modules

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

--

--

Ariful Islam
Ariful Islam

Written by Ariful Islam

Working on PHP, Laravel, CI, CakePHP, API. Open Source contributor, Cloud Expert, Project Consultant, Technical Writer. Owner at https://programmingmindset.com

No responses yet