spatie/laravel-superseeder
A Laravel package from Spatie for “super seeding”: convenient helpers and structure to build and run powerful database seeders, generate realistic test data, and quickly spin up complete demo environments with sensible defaults and relationships.
Installation
composer require spatie/laravel-superseeder
Publish the config file (optional):
php artisan vendor:publish --provider="Spatie\SuperSeeder\SuperSeederServiceProvider" --tag="superseeder-config"
First Use Case: Basic Seeding
Define a seeder class extending Spatie\SuperSeeder\SuperSeeder:
use Spatie\SuperSeeder\SuperSeeder;
use App\Models\User;
class UserSeeder extends SuperSeeder
{
public function run()
{
$this->seed(User::class, [
'name' => 'John Doe',
'email' => 'john@example.com',
'password' => bcrypt('password'),
]);
}
}
Run it via Artisan:
php artisan db:seed --class=UserSeeder
Where to Look First
config/superseeder.php (for default settings like batch size, retries).tests/ directory in the package for real-world usage patterns.Use with() to define relationships dynamically:
$this->seed(User::class, [
'name' => 'Jane Doe',
])
->with('posts', [
['title' => 'First Post', 'body' => 'Hello World'],
['title' => 'Second Post', 'body' => 'Laravel is awesome'],
]);
For large datasets, leverage chunking:
$this->seedMany(User::class, $users, 100); // Batch size of 100
Combine with Laravel’s factories for reusable data:
$this->seed(User::class, [
'name' => 'Factory User',
])->createUsing(User::factory());
Use when() to conditionally seed records:
$this->seed(User::class, [
'name' => 'Admin',
'role' => 'admin',
])->when(fn ($user) => $user->role === 'admin', function ($user) {
$user->posts()->create(['title' => 'Admin Post']);
});
UserSeeder, PostSeeder).php artisan db:seed --class=UserSeeder
php artisan db:seed --class=PostSeeder
DatabaseSeeder for one-command execution:
public function run()
{
$this->call([
UserSeeder::class,
PostSeeder::class,
]);
}
Seed test data in phpunit.xml:
<env name="DB_SEEDER_CLASS" value="TestSeeder"/>
Foreign Key Constraints
User) before child models (e.g., Post) to avoid SQLSTATE[23000] errors.DB::transaction(function () {
$this->seed(User::class, [...]);
$this->seed(Post::class, [...]);
});
Duplicate Data
unique() to enforce uniqueness (e.g., emails):
$this->seed(User::class, [
'email' => 'unique@example.com',
])->unique('email');
updateOrCreate for idempotent seeding:
User::updateOrCreate(['email' => 'john@example.com'], [
'name' => 'John Doe',
]);
Performance Bottlenecks
100; adjust in config/superseeder.php for memory constraints.DB::statement('ALTER TABLE users DISABLE TRIGGER ALL');
// Seed here
DB::statement('ALTER TABLE users ENABLE TRIGGER ALL');
Timestamps
created_at/updated_at are auto-filled. Disable with:
$this->seed(User::class, [...])->ignoreTimestamps();
Log Seeding Progress Use Laravel’s logging:
$this->seed(User::class, [...])->log();
Check storage/logs/laravel.log.
Validate Data
Use validate() to ensure data integrity:
$this->seed(User::class, [
'email' => 'invalid-email',
])->validate();
Rollback Failed Seeders Wrap in a transaction with rollback:
DB::transaction(function () {
try {
$this->seed(User::class, [...]);
} catch (\Exception $e) {
DB::rollBack();
throw $e;
}
});
Custom Seeders
Extend SuperSeeder to add domain-specific logic:
class CustomSeeder extends SuperSeeder
{
protected function afterSeed($model)
{
// Post-processing (e.g., send welcome email)
}
}
Data Sources
$data = json_decode(file_get_contents('data/users.json'), true);
$this->seedMany(User::class, $data);
$response = Http::get('https://api.example.com/users');
$this->seedMany(User::class, $response->json());
Event Listeners Trigger events after seeding:
event(new UsersSeeded($users));
Testing Helpers
Create a TestSeeder to reset state:
class TestSeeder extends SuperSeeder
{
public function run()
{
$this->truncateAll();
$this->seed(User::class, [...]);
}
}
How can I help you explore Laravel packages today?