Salta al contenuto principale

I Seeders, un utile strumento per popolare il database

Profile picture for user luca77king

I seeders sono classi che vengono utilizzate per popolare il database con dei dati. È un argomento essenziale quando si fa un refactoring o si ha bisogno di qualche dato per fare degli Unit Tests.

In questa lezione vedremo come creare dei dati fittizi, utilizzando la classe Faker di Laravel ma il seeder può essere utilizzato anche per importare i dati da un database già esistente o da un file excel.

Per creare un seeder, utilizziamo il seguente comando

php artisan make:seeder GenerateSomeFakeDatas

Il comando creerà un file nella directory database/seeders. In questo file, andremo a gestire il popolamento a cascata delle seguenti tabelle: users, producers e car_models.

Utilizzeremo due tecniche:

  • per la tabella users disponiamo già del relativo modello e quindi useremo le factory
  • per le altre due tabelle useremo un altro strumento, il Query Builder.

Le factory sono uno degli strumenti più utilizzati per generare dati fittizi nelle applicazioni Laravel. Queste classi si agganciano direttamente al relativo modello e indubbiamente fanno risparmiare moltissimo tempo. Per generare la factory basta lanciare il seguente comando, ovviamente impostando un modello già esistente

php artisan make:factory MyModel

Non abbiamo bisogno di creare la factory per gli utenti, dal momento che è già presente di default nella cartella database/factories.

Dobbiamo però modificare il metodo definition() visto che nella tabella abbiamo cambiato alcuni campi

public function definition()
{
    return [
    'first_name' => fake()->firstName(),
    'last_name' => fake()->lastName(),
    'email' => fake()->unique()->safeEmail(),
    'email_verified_at' => now(),
    'password' => bcrypt('123456789'),
    'remember_token' => Str::random(10)
    ];
}

Ora apriamo il seeder GenerateSomeFakeDatas e includiamo le dipendenze che ci servono

namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use App\Models\User;

Fatto questo, definiamo la dichiarazione per usare la factory degli utenti nel metodo run() del seeder

public function run()
{
    User::factory()->count(20)->create();
}

Da terminale facciamo girare il seeder con questo comando

php artisan db:seed --class=GenerateSomeFakeDatas

E andiamo a controllare la tabella users nel database

Nel caso volessimo omettere il parametro relativo alla classe da lanciare, dobbiamo agire sul seeder di default, DatabaseSeeder. Apriamolo e richiamiamo all’interno del metodo run() il nostro seeder GenerateSomeFakeDatas.

public function run()
{
    $this->call(GenerateSomeFakeDatas::class);
}

Così facendo, ogni volta che lanciamo il comando php artisan db:seed, saranno lanciati tutti i seeders inclusi nella classe di default.

Completiamo il nostro seeder, aggiungendo un pò di dati per le tabelle producers e car_models. Come detto, useremo il Query Builder, visto che non abbiamo ancora affrontato il discorso dei modelli di Laravel.

public function run()
{
    User::factory()->count(20)->create();
    for ($producer_counter = 1; $producer_counter <= 10; $producer_counter++) {
        $producer_id = DB::table('producers')->insertGetId([
        'name' => fake()->company,
        'created_at' => now(),
        'updated_at' => now()
        ]);
        $rand_number = random_int(2, 5);
        for ($models_counter = 1; $models_counter <= $rand_number; $models_counter++) {
            DB::table('car_models')->insert([
            'name' => fake()->firstNameFemale(),
            'price' => fake()->numberBetween(12000, 24540),
            'producer_id' => $producer_id,
            'created_at' => now(),
            'updated_at' => now()
            ]);
        }
    }
}

In questo codice ho impostato un ciclo di 10 iterazioni e attraverso il Query Builder ho popolato la tabella producers con un nome fittizio. Ho dovuto impostare i campi created_at e updated_at in quanto sono prerogative di Eloquent. Il metodo insertGetId() del Query Builder mi restituisce il PDO::lastInsertId che ho poi utilizzato nel ciclo successivo per legare i modelli delle automobili al relativo produttore.

Nella lezione successiva cominceremo a lavorare con Eloquent e tutto ciò diventerà un vago ricordo. Per adesso limitiamoci a lanciare il comando php artisan db:seed e al suo termine controlliamo che le tabelle delle database siano effettivamente popolate.