Formation PUB030 : Laravel, 2019 Création de la base de données et de ses tables

12.2 Les fichiers de migration : pour créer les tables de la BD


Pour créer ou modifier les tables de votre base de données, Laravel a prévu un système de fichiers de migration qui fonctionne à merveille.

À chaque fois qu'une table doit être créée ou modifiée, sa définition sera inscrite à l'aide d'instructions PHP précises, placées dans un fichier de migration. Une commande artisan permettra d'exécuter les lignes de code de ce fichier afin que les modifications soient effectuées dans la base de données.

Pour faciliter votre travail, prenez soin de créer un fichier de migration pour chaque table à créer. Si vous créez plusieurs tables dans un même fichier de migration, vous aurez moins de contrôle sur le processus de création / destruction des tables.

Laravel maintiendra dans la base de données une table nommée migrations dans laquelle les migrations effectuées seront listées. C'est à partir du contenu de cette table que Laravel saura quels fichiers doivent être exécutés lorsque vous lancez une migration.

Le principal avantage d'un tel système est de permettre à tous les membres de l'équipe de développement d'appliquer les mêmes modifications à leur base de données locale. De plus, puisque chaque fichier de migration est daté et correspond à une modification, il devient possible d'effectuer un suivi des versions de la structure de la base de données, ce qui est impossible avec une base de données compilée.

Important : pendant le développement de votre application, vous devez prendre soin de maintenir vos fichiers de migration à jour car c'est à partir d'eux que la base de données pourra être recréée le plus facilement.

Vous ne devez jamais travailler manuellement dans votre outil de gestion de bases de données pour ajouter une table ni pour en modifier la structure. TOUT DOIT PASSER PAR LES FICHIERS DE MIGRATION.

Si vous ne respectez pas ces principes, vous perdrez les avantages liés aux fichiers de migration.

▼Publicité Le texte se poursuit plus bas

Comment nommer les tables

Si vous souhaitez profiter des automatismes de Laravel, vous devez respecter les règles de nomenclature prévues.

Vous pourrez quand même programmer avec Laravel si vous ne le faites pas mais vous devrez spécifier des informations supplémentaires dans votre code car Laravel ne pourra pas faire tous les liens nécessaires par lui-même.

Voici donc les règles qu'il faut respecter pour faciliter votre travail :

  • Le nom des tables doit être au pluriel, entièrement en lettres minuscules.

    En effet, Laravel fera un lien automatique entre une table et une classe portant le même nom, mais au singulier (sans le s final). Ex : table categories vs classe Categorie.

    N'ayez crainte, un mécanisme, que nous verrons plus tard, permettra de traiter les exceptions, c'est-à-dire les mots dont le pluriel ne s'obtient pas en ajoutant un s. Ex : table travaux vs classe Travail, table typespaiement vs classe Typepaiement.

  • Dans le cas d'une table pivot utilisée dans une relation de plusieurs à plusieurs, Laravel s'attend à ce que le nom de la table soit composé du nom de chacune des tables, au singulier, séparés par une barre en bas. Les noms de tables seront en ordre alphabétique (ex : caracteristique_produit et non caracteristiques_produits ni produit_caracteristique).
  • L'identifiant de la table doit porter le nom id, en lettres minuscules. D'ailleurs, Laravel prévoit la méthode id() pour créer un champ nommé id, auto-incrémenté et de type big integer.

Suggestion : lorsque le nom d'une table est composé de deux mots mais que la table n'est pas une table pivot, placez ces mots côte-à-côte, sans barre de soulignement (ex : comptesbancaires). Ceci permettra de distinguer une telle table des tables pivot.

Autre suggestion : puisqu'avec Laravel, vous utiliserez le modèle pour accéder à vos tables, il n'est pas utile de préfixer les noms des champs pour les identifier à la table (ex : categorie_nom). Si on nomme le champ simplement nom, on référera à ce champ comme suit :

Contrôleur Laravel (PHP)

    $categorie->nom = ...;

Le code aurait été alourdi inutilement si le champ avait été nommé categorie_nom :

Contrôleur Laravel (PHP)

    $categorie->categorie_nom = ...;

Générer le fichier de migration pour créer une table

Un fichier de migration sera créé initialement à partir de la console SSH. Vous devez être placés dans le dossier de votre projet et entrer la commande artisan suivante :

Console Vagrant SSH

php artisan make:migration create_categories_table --create categories

Important : Puisque les fichiers de migration sont datés, il faut commencer par créer les fichiers de migration pour les tables qui contiennent les clés primaires avant ceux des tables qui contiennent les clés étrangères.

Dans notre exemple, puisqu'un produit contient une clé étrangère vers la table categories, il faudra créer le fichier de migration pour la table categories avant celui pour la table produits.

Le fichier de migration sera créé dans le dossier database\migrations, à la racine du projet. La date de création du fichier sera automatiquement ajoutée au début de son nom.

Le nom du fichier (ici : create_categories_table) n'a pas d'impact sur Laravel. L'important, c'est que le nom décrive bien ce qui sera exécuté par ce fichier (ici : créer la table categories).

Voici le code généré par la commande artisan :

Fichier de migration (PHP)

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateCategoriesTable extends Migration
{
    /**
    * Run the migrations.
    *
    * @return void
    */
    public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
             $table->id();
             $table->timestamps();
        });
    }

    /**
    * Reverse the migrations.
    *
    * @return void
    */
    public function down()
    {
        Schema::dropIfExists('categories');
    }

}

Éditer le fichier de migration

Vous devez maintenant éditer ce fichier pour définir votre table. Pour y arriver, vous travaillerez avec la façade Schema. Vous n'avez rien à installer pour cela, tout est déjà inclus dans Laravel.

La façade Schema offre trois principales méthodes statiques :

  • create() : pour créer une table
  • dropIfExists (ou drop()) : pour supprimer une table
  • table() : pour modifier une table

Méthode up()

Dans la méthode up(), entrez la définition de la table à l'aide de Schema::create() qui se chargera de créer la table.

Vous pouvez vous baser sur le code du fichier de migration create_users_table, founi avec votre projet Laravel, pour programmer votre nouveau fichier de migration.

Ex :

Fichier de migration (PHP)

public function up()

{

    Schema::create('categories', function (Blueprint $table) {

        $table->id();

        $table->string('nom', 100);

        $table->timestamps();

    });

}

Voici un autre exemple, pour une table contenant différents types de champs ainsi qu'une clé étrangère et sa contrainte d'intégrité référencielle :

Fichier de migration (PHP)

public function up()

{

    Schema::create('produits', function (Blueprint $table) {

        $table->id();

        $table->foreignId('categorie_id')->constrained();

        $table->string('nom', 100);

        $table->text('description')->nullable();

        $table->float('prix');

        $table->boolean('actif');

        $table->timestamps();

    });

}

Types de colonnes

Pour connaître le nom des méthodes pour chaque type de colonne, consultez la page https://laravel.com/docs/master/migrations#columns.

Notez que pour un champ défini à l'aide de la fonction string(), si vous ne précisez pas de longueur, il prendra la taille maximale disponible pour le type VARCHAR, c'est-à-dire 255.

Il est également possible de spécifier la taille désirée comme suit :

Fichier de migration (PHP)

$table->string('nomchamp', taille);

Notez que Laravel prévoit un système d'estampillage afin de maintenir pour chaque enregistrement la date de création et de dernière modification dans des champs nommés created_at et updated_at. À moins d'avoir une bonne raison de ne pas le faire, vous devriez ajouter une colonne avec la méthode timestamps() à chacune de vos tables.

Modificateurs de colonnes

Il est possible d'ajouter un modificateur de colonne. Parmi les plus utilisé, notons :

  • unique()
  • nullable()
  • unsigned()
  • default($value)

Clés étrangères et contraintes d'intégrité référentielle

Le nom des clés étrangères doit être au format nomtable_id, c'est-à-dire le nom de la table contenant la clé primaire, sans le s final, tout en lettres minuscule, suivi de _id (ex : categorie_id).

Il y a deux techniques pour créer une clé étrangère et sa contrainte d'intégrité référencielle.

Ceci est la méthode longue :

Fichier de migration (PHP)

$table->bigInteger('categorie_id')->unsigned();

$table->foreign('categorie_id')->references('id')->on('categories');

On peut faire l'équivalent en une seule ligne :

Fichier de migration (PHP)

$table->foreignId('categorie_id')->constrained('categories');

Si le nom de la table référencée par la contrainte respecte les règles de nomenclature, il est possible de raccourcir encore plus l'instruction :

PHP

$table->foreignId('categorie_id')->constrained();

Dans le cas où la clé étrangère peut prendre la valeur null, il faut ajouter nullable() AVANT constrained(). Ceci ne fonctionnera pas :

PHP

$table->foreignId('categorie_id')->constrained()->nullable();

 Il faut plutôt faire :

PHP

$table->foreignId('categorie_id')->nullable()->constrained();

Méthode down()

La méthode down() sera exécutée si on a besoin d'inverser une migration pour remettre la base de données telle qu'elle était avant la migration.

Typiquement, la méthode down() se charge de supprimer la table à l'aide de Schema::dropIfExists().

Ex :

Fichier de migration (PHP)

public function down()

{

    Schema::dropIfExists('categories');

}

Exécuter les fichiers de migration

Pour créer ou modifier les tables selon ce qui a été codé dans les fichiers de migration, utilisez la commande :

Console Vagrant SSH

php artisan migrate

Notez que cette commande exécutera, en ordre chronologique, la méthode up() de chacun des fichiers de migration présents dans le dossier database\migrations et qui n'ont pas été exécutés lors d'une précédente migration. Laravel utilisera la table migrations afin de savoir quels fichiers doivent être exécutés.

Avant d'exécuter les fichiers de migration, il peut être prudent de vérifier les lignes de code SQL qui seront générées :

Console Vagrant SSH

php artisan migrate --pretend

Inverser une migration

À chaque migration, Laravel conserve dans la table migrations la liste des fichiers exécutés. C'est pourquoi il est possible de défaire l'action effectuée lors de la dernière migration. C'est un peu comme si on faisait un « undo ».

Console Vagrant SSH

php artisan migrate:rollback

Cette commande exécutera la méthode down() de chacun des fichiers de migration impliqués lors de la dernière migration. Ici encore, c'est la table migrations qui dictera à Laravel quels fichiers doivent être exécutés.

Tester la concordance entre up() et down()

Pour vous assurer que la méthode down() fait bel et bien l'inverse de la méthode up(), il est conseillé d'effectuer le up() suivi du down() suivi du up() à nouveau. Si le résultat est bon, c'est que le premier up() a bel et bien été défait par le down() alors le second up() a été fait comme s'il n'y avait pas eu de up() et down() avant lui.

Console Vagrant SSH

php artisan migrate

php artisan migrate:rollback

php artisan migrate

Réinitialiser complètement la base de données

Lorsque rien ne va plus, mieux vaut parfois tout recommencer. Ceci est particulièrement vrai lorsque vous débutez le développement de votre base de données avec de nombreuses tables. Plusieurs essais et erreurs pourraient être nécessaires avant que vous parveniez au résultat escompté.

Vous n'avez aucun stress à avoir pendant le développement de vos fichiers de migration puisqu'une simple commande artisan peut se charger de faire un rollback complet de tous les fichiers de migration puis un migrate à partir du début.

Console Vagrant SSH

php artisan migrate:refresh

Dans le cas où vous avez en main les fichiers de seeds qui permettent d'insérer les données initiales et les données de tests, vous pouvez même demander à ce que les données soient insérées sur-le-champ dans les tables nouvellement créées.

Console Vagrant SSH

php artisan migrate:refresh --seed

Pour plus d'information

« Database: Migrations ». Laravel. https://laravel.com/docs/master/migrations

« Laravel 5 Fundamentals: Migrations ». Laracasts. https://laracasts.com/series/laravel-5-fundamentals/episodes/7

« Laravel Naming Conventions ». developed.be. http://developed.be/2013/08/21/laravel-naming-conventions/

« Renaming created_at & updated_at on Laravel Models ». Medium. https://medium.com/@smayzes/renaming-created-at-updated-at-on-laravel-models-235936f3ed84

Veuillez noter que le contenu de cette fiche vous est partagé à titre gracieux, au meilleur de mes connaissances et sans aucune garantie.
Par Christiane Lagacé
Dernière révision le 30 juin 2020
Merci de partager !

Site fièrement hébergé chez A2 Hosting.

Soumettre