DEV Community

Cover image for Laravel factory and seeder
Anas Hussain
Anas Hussain

Posted on

Laravel factory and seeder

1. Creating a Factory

Step 1: Generate the Factory

Run the following command to create a factory for your model:

php artisan make:factory ModelNameFactory --model=ModelName
Enter fullscreen mode Exit fullscreen mode

Example:

php artisan make:factory DepartmentFactory --model=Department
Enter fullscreen mode Exit fullscreen mode

This will create a file at database/factories/DepartmentFactory.php.

Step 2: Define the Factory

Open the factory file and define the data structure. Use realistic data for better testing.

namespace Database\Factories;

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

class DepartmentFactory extends Factory
{
    protected $model = Department::class;

    public function definition()
    {
        return [
            'name' => $this->faker->word, // Generates a random department name
            'description' => $this->faker->sentence, // Short description
            'created_at' => now(),
            'updated_at' => now(),
        ];
    }
}
Enter fullscreen mode Exit fullscreen mode

2. Creating a Seeder

Step 1: Generate the Seeder

Run the following command to create a seeder:

php artisan make:seeder SeederName
Enter fullscreen mode Exit fullscreen mode

Example:

php artisan make:seeder DepartmentSeeder
Enter fullscreen mode Exit fullscreen mode

This will create a file at database/seeders/DepartmentSeeder.php.

Step 2: Define the Seeder

In the seeder file, use the factory to generate records.

namespace Database\Seeders;

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

class DepartmentSeeder extends Seeder
{
    public function run()
    {
        // Generate 10 departments
        Department::factory(10)->create();
    }
}
Enter fullscreen mode Exit fullscreen mode

3. Register the Seeder

Step 1: Add Seeder to DatabaseSeeder

In database/seeders/DatabaseSeeder.php, call the DepartmentSeeder:

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        $this->call([
            DepartmentSeeder::class,
        ]);
    }
}
Enter fullscreen mode Exit fullscreen mode

4. Run the Seeder

Run the following command to seed your database:

php artisan db:seed
Enter fullscreen mode Exit fullscreen mode

To run a specific seeder:

php artisan db:seed --class=DepartmentSeeder
Enter fullscreen mode Exit fullscreen mode

5. Professional Practices

  1. Use Relationships in Factories If your model has relationships, define them in the factory:
   'user_id' => User::factory(), // Generates a user and assigns it to this model
Enter fullscreen mode Exit fullscreen mode
  1. Use Custom States Create states for specific variations of the model:
   public function admin()
   {
       return $this->state([
           'role' => 'admin',
       ]);
   }
Enter fullscreen mode Exit fullscreen mode

Use it in seeders:

   Department::factory()->admin()->create();
Enter fullscreen mode Exit fullscreen mode
  1. Organize Seeders For large projects, organize seeders into modules:
   database/
   └── seeders/
       ├── Admin/
       │   ├── UserSeeder.php
       │   └── RoleSeeder.php
       ├── Product/
       │   └── ProductSeeder.php
       └── DepartmentSeeder.php
Enter fullscreen mode Exit fullscreen mode
  1. Testing with Factories Use factories in tests to generate test data:
   $department = Department::factory()->create();
   $this->assertDatabaseHas('departments', ['id' => $department->id]);
Enter fullscreen mode Exit fullscreen mode
  1. Clear and Seed For fresh testing, run:
   php artisan migrate:fresh --seed
Enter fullscreen mode Exit fullscreen mode

6. Example Usage

If you have a Department model, you can now generate:

  • Random departments:
  Department::factory()->count(10)->create();
Enter fullscreen mode Exit fullscreen mode
  • Custom departments:
  Department::factory()->create([
      'name' => 'Human Resources',
  ]);
Enter fullscreen mode Exit fullscreen mode

Top comments (0)