SyntaxStudy
Sign Up
Laravel Seeders, Factories, and Fake Data
Laravel Beginner 1 min read

Seeders, Factories, and Fake Data

Database seeders populate tables with test or default data. Seeders extend Illuminate\Database\Seeder and implement a run() method. The DatabaseSeeder class is the root seeder that calls child seeders via $this->call(). Run seeders with php artisan db:seed or combine them with migrations using php artisan migrate --seed. Model factories generate fake model instances for testing and seeding. A factory class extends Illuminate\Database\Eloquent\Factories\Factory and its definition() method returns an array of default attribute values, typically using Faker (bundled via FakerPHP). Calling User::factory()->create() persists a record, while ::make() creates an in-memory instance. ::factory(50)->create() generates 50 records at once. Factory states allow defining named variations of a model. A state method calls the state() helper and returns a closure that merges additional attributes. For example, User::factory()->admin()->create() would apply an admin state that sets the role attribute. Factories support relationships through the for() and has() methods, enabling complex nested data generation in a single readable chain.
Example
<?php
// database/factories/PostFactory.php

namespace Database\Factories;

use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

class PostFactory extends Factory
{
    public function definition(): array
    {
        $title = $this->faker->sentence(6);
        return [
            'user_id'      => User::factory(),
            'title'        => $title,
            'slug'         => Str::slug($title),
            'body'         => $this->faker->paragraphs(4, true),
            'status'       => $this->faker->randomElement(['draft', 'published']),
            'published_at' => $this->faker->optional()->dateTimeThisYear(),
        ];
    }

    public function published(): static
    {
        return $this->state(fn(array $attrs) => [
            'status'       => 'published',
            'published_at' => now()->subDays(rand(1, 30)),
        ]);
    }
}

// database/seeders/PostSeeder.php
class PostSeeder extends Seeder
{
    public function run(): void
    {
        \App\Models\Post::factory(50)->published()->create();
    }
}