<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run(): void
{
if (app()->environment('production')) {
$this->command->warn('Skipping seeders in production');
return;
}
$this->call([
UserSeeder::class,
CategorySeeder::class,
PostSeeder::class,
CommentSeeder::class,
]);
}
}
<?php
namespace Database\Seeders;
use App\Models\Post;
use App\Models\User;
use App\Models\Tag;
use Illuminate\Database\Seeder;
class PostSeeder extends Seeder
{
public function run(): void
{
$users = User::all();
$tags = Tag::all();
// Create 50 published posts
Post::factory()
->count(50)
->published()
->create()
->each(function ($post) use ($users, $tags) {
// Assign random author
$post->user_id = $users->random()->id;
$post->save();
// Attach random tags
$post->tags()->attach(
$tags->random(rand(1, 5))->pluck('id')
);
// Create comments
$post->comments()
->createMany(
\App\Models\Comment::factory()
->count(rand(0, 10))
->make()
->toArray()
);
});
// Create 20 draft posts
Post::factory()
->count(20)
->draft()
->create();
}
}
<?php
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class PostFactory extends Factory
{
public function definition(): array
{
return [
'user_id' => User::factory(),
'title' => fake()->sentence(),
'slug' => fake()->slug(),
'body' => fake()->paragraphs(5, true),
'excerpt' => fake()->paragraph(),
'views' => fake()->numberBetween(0, 10000),
'published_at' => null,
];
}
public function published(): static
{
return $this->state(fn (array $attributes) => [
'published_at' => fake()->dateTimeBetween('-1 year', 'now'),
]);
}
public function draft(): static
{
return $this->state(fn (array $attributes) => [
'published_at' => null,
]);
}
public function featured(): static
{
return $this->state(fn (array $attributes) => [
'is_featured' => true,
'views' => fake()->numberBetween(5000, 50000),
]);
}
}
Seeders populate databases with test or initial data. I create seeder classes in database/seeders with a run() method. The DatabaseSeeder orchestrates other seeders. For large datasets, I use factories with factory()->count(100)->create() for performance. Model factories define default attributes and states for variations. Seeders support environments—only run certain seeders in development. I use transactions in seeders to roll back on errors. The --class flag runs specific seeders without running all. Seeders are perfect for demo data, development databases, or initial application setup. Combined with migrations, they enable reproducible database states across environments.