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!

MK
la source

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();
Johan
la source
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

MK
la source
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

Chris Barrett
la source
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.

Mark Kendall
la source