Laravel

How to Use Laravel Seeders and Factories

Administrator
By Administrator
Published Oct 07, 2025
10 min read
How to Use Laravel Seeders and Factories

How to Use Laravel Seeders and Factories

Laravel seeders and factories are powerful tools for populating your database with test data. Factories allow you to define models with dummy data, while seeders use those factories to populate your database with large amounts of data. This comprehensive guide will walk you through everything you need to know about using Laravel seeders and factories effectively.

What are Factories and Seeders?

Factories

Factories are PHP classes that define how to create instances of Eloquent models. They generate realistic dummy data that follows the same structure as your real data.

Seeders

Seeders are classes that contain logic to populate your database with data. They can use factories to create realistic test data or insert raw data directly into your database.

Creating Factories

Using Artisan Commands

Generate factory files using Artisan commands:

// Create a basic factory
php artisan make:factory UserFactory

// Create a factory for a specific model
php artisan make:factory UserFactory --model=User

// Create multiple factories
php artisan make:factory UserFactory --model=User
php artisan make:factory PostFactory --model=Post
php artisan make:factory CommentFactory --model=Comment

// Create factory with specific path
php artisan make:factory UserFactory --path=database/factories/custom

Basic Factory Structure

Here's what a basic factory file looks like:

<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

class UserFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'name' => fake()->name(),
            'email' => fake()->unique()->safeEmail(),
            'email_verified_at' => now(),
            'password' => bcrypt('password'), // password
            'remember_token' => str_random(10),
        ];
    }
}

Factory States

Creating States

Add different states to your factories for varied test data:

<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

class UserFactory extends Factory
{
    public function definition()
    {
        return [
            'name' => fake()->name(),
            'email' => fake()->unique()->safeEmail(),
            'email_verified_at' => now(),
            'password' => bcrypt('password'),
            'remember_token' => str_random(10),
        ];
    }

    // Factory state for admin users
    public function admin()
    {
        return $this->state(function (array $attributes) {
            return [
                'name' => 'Admin User',
                'email' => '[email protected]',
                'role' => 'admin',
            ];
        });
    }

    // Factory state for inactive users
    public function inactive()
    {
        return $this->state(function (array $attributes) {
            return [
                'active' => false,
                'email_verified_at' => null,
            ];
        });
    }

    // Factory state for users with specific age
    public function withAge($age)
    {
        return $this->state(function (array $attributes) use ($age) {
            return [
                'age' => $age,
            ];
        });
    }
}

Using Factory States

Apply states when creating models:

// Using factory states
$admin = User::factory()->admin()->create();
$inactiveUser = User::factory()->inactive()->create();
$youngUser = User::factory()->withAge(25)->create();

// Combining multiple states
$inactiveAdmin = User::factory()
    ->admin()
    ->inactive()
    ->create();

// Creating multiple records with state
$users = User::factory()->count(10)->admin()->create();

// Creating with state and attributes
$user = User::factory()
    ->admin()
    ->create(['name' => 'Custom Admin Name']);

Factory Relationships

Defining Relationships

Create relationships between factory models:

<?php

namespace Database\Factories;

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

class PostFactory extends Factory
{
    public function definition()
    {
        return [
            'title' => fake()->sentence(),
            'content' => fake()->paragraphs(3, true),
            'published_at' => fake()->dateTimeThisYear(),
            'user_id' => User::factory(),
        ];
    }

    // Relationship for posts with a specific user
    public function forUser(User $user)
    {
        return $this->state(function (array $attributes) use ($user) {
            return [
                'user_id' => $user->id,
            ];
        });
    }

    // Relationship for published posts
    public function published()
    {
        return $this->state(function (array $attributes) {
            return [
                'published_at' => fake()->dateTimeThisYear(),
                'status' => 'published',
            ];
        });
    }
}

// Usage
$user = User::factory()->create();
$post = Post::factory()->forUser($user)->create();
$publishedPost = Post::factory()->published()->create();

Complex Relationship Factories

Create more complex relationships:

<?php

namespace Database\Factories;

use App\Models\User;
use App\Models\Post;
use App\Models\Comment;
use Illuminate\Database\Eloquent\Factories\Factory;

class CommentFactory extends Factory
{
    public function definition()
    {
        return [
            'content' => fake()->paragraph(),
            'user_id' => User::factory(),
            'post_id' => Post::factory(),
        ];
    }

    // Comment for specific post
    public function forPost(Post $post)
    {
        return $this->state(function (array $attributes) use ($post) {
            return [
                'post_id' => $post->id,
            ];
        });
    }

    // Comment for specific user
    public function forUser(User $user)
    {
        return $this->state(function (array $attributes) use ($user) {
            return [
                'user_id' => $user->id,
            ];
        });
    }

    // Reply to another comment
    public function replyTo(Comment $parentComment)
    {
        return $this->state(function (array $attributes) use ($parentComment) {
            return [
                'post_id' => $parentComment->post_id,
                'parent_id' => $parentComment->id,
            ];
        });
    }
}

// Usage
$post = Post::factory()->create();
$comment = Comment::factory()->forPost($post)->create();
$reply = Comment::factory()->replyTo($comment)->create();

Creating Seeders

Using Artisan Commands

Generate seeder files using Artisan commands:

// Create a basic seeder
php artisan make:seeder UserSeeder

// Create multiple seeders
php artisan make:seeder UserSeeder
php artisan make:seeder PostSeeder
php artisan make:seeder CommentSeeder

// Create seeder with specific path
php artisan make:seeder UserSeeder --path=database/seeders/custom

Basic Seeder Structure

Here's what a basic seeder file looks like:

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\User;

class UserSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // Create a single user
        User::create([
            'name' => 'Admin User',
            'email' => '[email protected]',
            'password' => bcrypt('password'),
            'role' => 'admin',
        ]);

        // Create multiple users
        User::insert([
            ['name' => 'John Doe', 'email' => '[email protected]', 'password' => bcrypt('password')],
            ['name' => 'Jane Smith', 'email' => '[email protected]', 'password' => bcrypt('password')],
            ['name' => 'Bob Johnson', 'email' => '[email protected]', 'password' => bcrypt('password')],
        ]);

        // Use factories to create users
        User::factory(10)->create();
    }
}

Advanced Seeder Techniques

Using Faker for Realistic Data

Generate realistic test data with Faker:

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\User;
use App\Models\Post;
use App\Models\Comment;

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        // Create users with different roles
        $users = User::factory()->count(20)->create();
        $admin = User::factory()->admin()->create();

        // Create posts for all users
        $posts = Post::factory()->count(50)->create()->each(function ($post) use ($users) {
            // Create comments for each post
            Comment::factory()
                ->count(rand(1, 10))
                ->forPost($post)
                ->create();
        });

        // Create additional relationships
        $users->each(function ($user) {
            // Create posts for each user
            Post::factory()
                ->count(rand(1, 5))
                ->forUser($user)
                ->create();
        });

        // Create popular posts with many comments
        Post::factory()
            ->count(10)
            ->published()
            ->has(Comment::factory()->count(20), 'comments')
            ->create();
    }
}

Conditional Data Creation

Create data based on conditions:

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\Post;

class PostSeeder extends Seeder
{
    public function run()
    {
        // Create published posts
        Post::factory()
            ->count(20)
            ->published()
            ->create();

        // Create draft posts
        Post::factory()
            ->count(10)
            ->state(['status' => 'draft'])
            ->create();

        // Create featured posts
        Post::factory()
            ->count(5)
            ->published()
            ->featured()
            ->create();

        // Create posts with specific categories
        $categories = ['Technology', 'Business', 'Health', 'Education'];

        foreach ($categories as $category) {
            Post::factory()
                ->count(15)
                ->published()
                ->state(['category' => $category])
                ->create();
        }
    }
}

Running Seeders

Basic Seeder Commands

Execute seeders with Artisan commands:

// Run all seeders
php artisan db:seed

// Run a specific seeder
php artisan db:seed --class=UserSeeder

// Run seeders with force
php artisan db:seed --force

// Run seeders in production
php artisan db:seed --force

// Run seeder and all migrations
php artisan migrate:fresh --seed

// Run seeder and specific migrations
php artisan migrate:fresh --seed --path=database/migrations/2023_01_01_000000_create_users_table.php

Production Seeding

Production Data Seeder

Create seeders for production data:

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\User;
use App\Models\Category;
use App\Models\Post;
use App\Models\Setting;

class ProductionSeeder extends Seeder
{
    public function run()
    {
        // Create default admin user
        $admin = User::create([
            'name' => 'Admin User',
            'email' => '[email protected]',
            'password' => bcrypt('admin123'),
            'role' => 'admin',
            'active' => true,
        ]);

        // Create default categories
        $categories = [
            ['name' => 'Technology', 'slug' => 'technology', 'description' => 'Technology related posts'],
            ['name' => 'Business', 'slug' => 'business', 'description' => 'Business related posts'],
            ['name' => 'Health', 'slug' => 'health', 'description' => 'Health related posts'],
            ['name' => 'Education', 'slug' => 'education', 'description' => 'Education related posts'],
        ];

        foreach ($categories as $category) {
            Category::create($category);
        }

        // Create default settings
        $settings = [
            ['key' => 'site_name', 'value' => 'My Blog'],
            ['key' => 'site_description', 'value' => 'A professional blog website'],
            ['key' => 'site_keywords', 'value' => 'blog, technology, business, health'],
            ['key' => 'site_author', 'value' => 'Admin User'],
            ['key' => 'site_url', 'value' => 'https://myblog.com'],
        ];

        foreach ($settings as $setting) {
            Setting::create($setting);
        }

        // Create featured posts
        Post::factory()
            ->count(5)
            ->published()
            ->featured()
            ->create();
    }
}

Faker Library Usage

Faker Methods

Use Faker methods to generate realistic data:

<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

class UserFactory extends Factory
{
    public function definition()
    {
        return [
            // Personal information
            'name' => fake()->name(),
            'email' => fake()->unique()->safeEmail(),
            'phone' => fake()->phoneNumber(),
            'address' => fake()->address(),
            'city' => fake()->city(),
            'state' => fake()->state(),
            'zip' => fake()->postcode(),
            'country' => fake()->country(),

            // Personal details
            'date_of_birth' => fake()->date(),
            'gender' => fake()->randomElement(['male', 'female', 'other']),
            'age' => fake()->numberBetween(18, 80),

            // Professional information
            'job_title' => fake()->jobTitle(),
            'company' => fake()->company(),
            'department' => fake()->word(),
            'salary' => fake()->numberBetween(30000, 150000),

            // Random data
            'favorite_color' => fake()->colorName(),
            'favorite_food' => fake()->word(),
            'hobby' => fake()->word(),
            'bio' => fake()->paragraph(),

            // Internet-related
            'website' => fake()->url(),
            'linkedin' => fake()->url(),
            'twitter' => fake()->userName(),
            'github' => fake()->userName(),

            // Number generation
            'score' => fake()->numberBetween(0, 100),
            'rating' => fake()->numberBetween(1, 5),
            'count' => fake()->numberBetween(1, 1000),
            'percentage' => fake()->numberBetween(0, 100),

            // Text generation
            'title' => fake()->sentence(3),
            'subtitle' => fake()->sentence(6),
            'summary' => fake()->paragraph(3),
            'description' => fake()->paragraphs(3, true),
            'content' => fake()->paragraphs(10, true),

            // Date and time
            'last_login' => fake()->dateTimeThisMonth(),
            'created_at' => fake()->dateTimeThisYear(),
            'updated_at' => fake()->dateTimeThisYear(),
        ];
    }
}

Best Practices

Factory Best Practices

Follow these best practices for your factories:

// Use consistent naming conventions
UserFactory::class
PostFactory::class
CommentFactory::class

// Keep factories simple and focused
public function definition()
{
    return [
        'name' => fake()->name(),
        'email' => fake()->unique()->safeEmail(),
        'password' => bcrypt('password'),
    ];
}

// Use meaningful state names
public function admin()
public function active()
public function featured()
public function recent()

// Avoid complex logic in factories
public function definition()
{
    return [
        'name' => fake()->name(),
        'email' => fake()->unique()->safeEmail(),
        'password' => bcrypt('password'),
    ];
}

// Use factories for test data, not production data
// Use seeders for production or static data

Seeder Best Practices

Follow these best practices for your seeders:

// Organize seeders logically
DatabaseSeeder::class
UserSeeder::class
PostSeeder::class
CommentSeeder::class
CategorySeeder::class

// Use proper data relationships
public function run()
{
    $users = User::factory()->count(10)->create();
    $posts = Post::factory()->count(50)->create();

    $posts->each(function ($post) use ($users) {
        $post->comments()->saveMany(
            Comment::factory()->count(rand(1, 5))->make()
        );
    });
}

// Don't use seeders for large datasets
// Use database imports or scripts instead

Real-World Examples

E-commerce Seeder

Complete e-commerce seeder example:

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\User;
use App\Models\Product;
use App\Models\Category;
use App\Models\Order;
use App\Models\OrderItem;

class EcommerceSeeder extends Seeder
{
    public function run()
    {
        // Create categories
        $categories = Category::factory()->count(10)->create();

        // Create users
        $customers = User::factory()->count(50)->create();
        $admin = User::factory()->admin()->create();

        // Create products
        $products = Product::factory()->count(100)->create()->each(function ($product) use ($categories) {
            // Assign random category to each product
            $product->categories()->attach($categories->random(rand(1, 3)));
        });

        // Create orders
        $orders = Order::factory()->count(200)->create()->each(function ($order) use ($customers, $products) {
            // Add order items
            $items = rand(1, 5);
            $total = 0;

            for ($i = 0; $i < $items; $i++) {
                $product = $products->random();
                $quantity = rand(1, 3);
                $price = $product->price;
                $total += $price * $quantity;

                OrderItem::create([
                    'order_id' => $order->id,
                    'product_id' => $product->id,
                    'quantity' => $quantity,
                    'price' => $price,
                    'total' => $price * $quantity,
                ]);
            }

            // Update order total
            $order->update(['total' => $total]);
        });
    }
}

Conclusion

Laravel seeders and factories are essential tools for testing and development. By understanding how to create realistic test data and properly seed your database, you can build more robust applications and catch issues early in the development process.

Key takeaways:

  • Use factories for generating realistic test data
  • Define meaningful states for different scenarios
  • Create proper relationships between models
  • Use seeders for production data and static content
  • Follow best practices for maintainability
  • Test thoroughly before production

With seeders and factories, you can efficiently manage test data and focus on building great applications. Happy coding! 🚀

Related Articles

Using Laravel Sanctum for API Authentication

Using Laravel Sanctum for API Authentication

Oct 07, 2025

Introduction to Laravel Sanctum Laravel Sanctum is a simple authentication library for SPAs (Sing...

How to Send Emails in Laravel Using Mailables

How to Send Emails in Laravel Using Mailables

Oct 07, 2025

Introduction to Laravel Mailables Sending emails in Laravel has never been easier thanks to Maila...

Laravel Queues and Jobs: Complete Beginner's Guide

Laravel Queues and Jobs: Complete Beginner's Guide

Oct 07, 2025

What Are Laravel Queues? Laravel Queues allow you to defer processing of time-consuming tasks. In...

How to Handle File Uploads in Laravel

How to Handle File Uploads in Laravel

Oct 07, 2025

Introduction to File Uploads in Laravel File uploads are a fundamental feature in most web applic...