11 votes

Problème de clé étrangère auto-référencée lors de la migration vers Laravel

Bonjour, j'ai un problème pour créer une table à l'aide de migration schema builder. Le problème survient avec une table dont la clé étrangère est auto-référencée. Voici le code qui produit l'erreur :

        Schema::create('cb_category', function($table)
    {
        $table->integer('id')->primary()->unique()->unsigned();
        $table->integer('domain_id')->unsigned();
        $table->foreign('domain_id')->references('id')->on('cb_domain'); 
        $table->integer('parent_id')->nullable(); 
        $table->foreign('parent_id')->references('id')->on('cb_category')->onUpdate('cascade')->onDelete('cascade'); 
        $table->string('name');
        $table->integer('level');
    });

Voici l'erreur :

  SQLSTATE[HY000]: General error: 1005 Can't create table 'eklik2.#sql-7d4_e' (errno: 150) (SQL: alter table `cb_cate

sanglant add constraint cb_category_parent_id_foreign foreign key ( parent_id ) references cb_category ( i ete cascade on update cascade) (Bindings : array ( ))

[ SQLSTATE[HY000] : Erreur générale : 1005 Impossible de créer la table 'eklik2.#sql-7d4_e' (errno : 150)

Une idée ?

12voto

Meroje Points 344

Vous devez diviser cela en deux blocs de schéma, l'un créant les colonnes, l'autre ajoutant les FK. mysql ne peut pas faire les deux en même temps.

10voto

Isaac Limón Points 649

Deux querys fonctionnent :

Schema::create('cb_category', function($table)
{
    $table->integer('id')->primary()->unique()->unsigned();
    $table->integer('parent_id')->nullable();  
});

Schema::table('cb_category', function (Blueprint $table) 
{
    $table->foreign('parent_id')->references('id')->on('cb_category')->onUpdate('cascade')->onDelete('cascade');
});

8voto

ioni Points 8

J'arrive peut-être trop tard, mais les documents officiels affirment que la clé étrangère, dans le cas d'un nombre entier, doit être ->unsigned();

http://laravel.com/docs/4.2/schema#foreign-keys

Remarque : lors de la création d'une clé étrangère qui fait référence à un nombre entier incrémentiel, n'oubliez pas de toujours rendre la clé étrangère n'oubliez pas de toujours rendre la colonne de la clé étrangère non signée.

De plus, Artisan n'échoue pas si vous faites une faute d'orthographe (comme je l'ai fait). unsigned() et j'ai passé plusieurs heures à essayer de comprendre pourquoi la clé n'était pas créée.

Deux choses donc : 1. Toujours faire en sorte que la colonne de la clé étrangère ne soit pas signée en cas d'incrémentation des nombres entiers. 2. Vérifier l'orthographe de unsigned()

3voto

florianb Points 718

Une réponse tardive également, mais probablement plus idiomatique voie pour Laravel 8 :

use App\Models\CbCategory;

...

Schema::create("cb_category", function(Blueprint $table)
{
    $table->id();
    $table->foreignIdFor(CbCategory::class, "parent_id")
        ->constrained()
        ->cascadeOnUpdate()
        ->cascadeOnDelete()
        ->nullable();
});

A noter : J'ai deviné le nom de la classe CbCategory ici. L'utilisation de la référence de la classe (au lieu de l'ancienne chaîne du nom de la table) permet aux vérificateurs de code statique de détecter les futurs changements de nom de la classe.
De même, le _id -suffixe au parent_id Le nom de la colonne est important.


Puissent les ressources suivantes étancher votre soif de connaissances :

0voto

krunal nerikar Points 428
Schema::create('cb_category', function (Blueprint $table) {
        $table->increments('id')->unsigned();
        $table->integer('domain_id')->unsigned();
        $table->foreign('domain_id')->references('id')->on('cb_domain');
        $table->integer('parent_id')->nullable();
        $table->foreign('parent_id')->references('id')->on('cb_category')->onUpdate('cascade')->onDelete('cascade');
        $table->string('name');
        $table->integer('level');
    });

Essayez ceci

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X