Chapitre 7Projet SunuLearn

Seeders et Factories — remplir la base

Données de test réalistes avec Faker

Concepts Théoriques

Travailler avec une base vide est pénible — pas de données à afficher, impossible de tester les filtres, le catalogue est vide. Les Factories génèrent des données fictives réalistes. Les Seeders orchestrent le remplissage. Ensemble, ils remplissent la base en une commande.

Factories — générer des données réalistes

Une factory définit comment créer une instance d'un modèle avec des données aléatoires :

// database/factories/FormationFactory.php
class FormationFactory extends Factory
{
    public function definition(): array
    {
        $title = fake()->unique()->randomElement([
            'HTML, CSS, JavaScript', 'PHP', 'Laravel 12',
            'SQL & MySQL', 'Git & GitHub', 'Prompt Engineering',
        ]);

        return [
            'title' => $title,
            'slug' => Str::slug($title),
            'short_description' => fake()->sentence(15),
            'description' => fake()->paragraphs(3, true),
            'category_id' => Category::factory(),
            'level' => fake()->randomElement(['debutant', 'intermediaire', 'avance']),
            'duration' => '~' . fake()->numberBetween(10, 40) . 'h',
            'chapters_count' => fake()->numberBetween(10, 20),
            'is_published' => true,
            'is_featured' => fake()->boolean(30),
            'is_free' => true,
        ];
    }
}

fake() utilise la bibliothèque Faker pour générer des noms, textes, emails, dates aléatoires. fake()->sentence(), fake()->name(), fake()->email(), fake()->numberBetween(1, 100), etc.

Seeders — orchestrer le remplissage

// database/seeders/DatabaseSeeder.php
class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        // Catégories fixes (pas aléatoires — elles ont un sens métier)
        $categories = [
            ['name' => 'Frontend', 'slug' => 'frontend', 'color' => '#2563eb'],
            ['name' => 'Backend', 'slug' => 'backend', 'color' => '#0891b2'],
            ['name' => 'DevOps', 'slug' => 'devops', 'color' => '#16a34a'],
            ['name' => 'IA', 'slug' => 'ia', 'color' => '#7c3aed'],
        ];

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

        // Formations
        Formation::factory()->count(12)->create();

        // Chapitres pour chaque formation
        Formation::all()->each(function ($formation) {
            Chapter::factory()
                ->count($formation->chapters_count)
                ->sequence(fn ($sequence) => ['number' => $sequence->index, 'order' => $sequence->index])
                ->create(['formation_id' => $formation->id]);
        });

        // Utilisateurs
        User::factory()->count(10)->create();

        // Un admin connu
        User::factory()->create([
            'name' => 'Admin SunuLearn',
            'email' => 'admin@sunulearn.com',
            'password' => bcrypt('password'),
        ]);
    }
}

Exécuter le seeding

php artisan db:seed                    # Exécuter le seeder
php artisan migrate:fresh --seed       # Tout recréer + seeder (dev seulement !)