Laravel Schema onDelete set null


112

Impossible de comprendre comment définir une contrainte onDelete appropriée sur une table dans Laravel. (Je travaille avec SqLite)

$table->...->onDelete('cascade'); // works
$table->...->onDelete('null || set null'); // neither of them work

J'ai 3 migrations, créant la table de la galerie:

Schema::create('galleries', function($table)
{
    $table->increments('id');
    $table->string('name')->unique();
    $table->text('path')->unique();
    $table->text('description')->nullable();
    $table->timestamps();
    $table->engine = 'InnoDB';
});

Création du tableau des images:

Schema::create('pictures', function($table)
{
    $table->increments('id');
    $table->text('path');
    $table->string('title')->nullable();
    $table->text('description')->nullable();
    $table->integer('gallery_id')->unsigned();
    $table->foreign('gallery_id')
        ->references('id')->on('galleries')
        ->onDelete('cascade');
    $table->timestamps();
    $table->engine = 'InnoDB';
});

Lier la table de la galerie à une image:

Schema::table('galleries', function($table)
{
    // id of a picture that is used as cover for a gallery
    $table->integer('picture_id')->after('description')
        ->unsigned()->nullable();
    $table->foreign('picture_id')
        ->references('id')->on('pictures')
        ->onDelete('cascade || set null || null'); // neither of them works
});

Je ne reçois aucune erreur. De plus, même l'option "cascade" ne fonctionne pas (uniquement sur la table de la galerie). La suppression d'une galerie supprime toutes les images. Mais la suppression de l'image de couverture ne supprimera pas la galerie (à des fins de test).

Etant donné que même la "cascade" n'est pas déclenchée, je "set null" n'est pas le problème.

EDIT (solution de contournement):

Après avoir lu cet article, j'ai un peu changé mon schéma. Maintenant, le tableau des images contient une cellule "is_cover", qui indique si cette image est une couverture de son album ou non.

Une solution au problème d'origine est toujours très appréciée!

Réponses:


318

Si vous souhaitez définir null lors de la suppression:

$table->...->onDelete('set null');

Assurez-vous d'abord de définir le champ de clé étrangère comme nullable:

$table->integer('foreign_id')->unsigned()->nullable();

37
plus pour->nullable()
mohsenJsh

3
Existe-t-il une documentation Laravel à ce sujet?
Chuck Le Butt

laravel.com/docs/6.x/migrations#foreign-key-constraints il ne documente pas les options disponibles, mais je pense que vous pouvez supposer que ce sont les valeurs par défaut de mysql (voir ../ vendor / laravel / framework / src / Illuminate / Database / Schema / Grammars / Grammar.php)
Dirk

6
  • Il s'agit d'un problème connu dans Laravel. Plus d'informations à ce sujet ici .

  • Cette fonctionnalité n'est pas prise en charge dans SQLite, voir ici

  • Également un sujet qui présente une confrontation détaillée de ce problème


1
@SimonBengtsson Le problème doit avoir été fermé ou supprimé.
MK

5

Selon

http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html

$ table-> onDelete ('set null') devrait fonctionner avant d'essayer

$table->...->onDelete(DB::raw('set null'));

S'il y a des erreurs, serait également utile


Vous pourriez vouloir revenir en arrière, écrire le sql à la main, puis exécuter et exécuter des tests sur local. Tout ce que je peux trouver dit que cela devrait fonctionner dev.mysql.com/doc/refman/5.6/en/… , pourrait être un problème pour générer le sql
Chris Barrett

Merci! Malheureusement, cela a entraîné le même problème. Je pense que c'est quelque chose de spécifique à SqLite et aux références circulaires.
MK

Plus un car onDelete ('set null') fonctionne avec mysql.
Simon Bengtsson

3

En utilisant Laravel 4.2 sur MySQL 5.5 avec InnoDB, onDelete ('set null') fonctionne.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.