Schemat Laravel onDelete ustawiono na null

112

Nie mogę dowiedzieć się, jak ustawić odpowiednie ograniczenie onDelete dla tabeli w Laravel. (Pracuję z SqLite)

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

Mam 3 migracje, tworząc tabelę galerii:

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';
});

Tworzenie tabeli zdjęć:

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';
});

Łączenie tabeli galerii ze zdjęciem:

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
});

Nie otrzymuję żadnych błędów. Ponadto nawet opcja „kaskada” nie działa (tylko w tabeli galerii). Usunięcie galerii powoduje usunięcie wszystkich zdjęć. Ale usunięcie zdjęcia na okładkę nie spowoduje usunięcia galerii (do celów testowych).

Ponieważ nawet „kaskada” nie jest wyzwalana, „ustawiam wartość null” nie stanowi problemu.

EDYTUJ (obejście):

Po przeczytaniu tego artykułu zmieniłem nieco schemat. Teraz tabela obrazów zawiera komórkę „is_cover”, która wskazuje, czy to zdjęcie jest okładką albumu, czy nie.

Rozwiązanie pierwotnego problemu jest nadal wysoko cenione!

MK
źródło

Odpowiedzi:

318

Jeśli chcesz ustawić null przy usuwaniu:

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

Najpierw upewnij się, że pole klucza obcego jest ustawione na wartość null:

$table->integer('foreign_id')->unsigned()->nullable();
Johan
źródło
37
plus za->nullable()
mohsenJsh
3
Czy jest jakaś dokumentacja Laravel na ten temat?
Chuck Le Butt
laravel.com/docs/6.x/migrations#foreign-key-constraints nie dokumentuje, jakie są opcje, ale myślę, że możesz założyć, że są to domyślne wartości mysql (patrz ../ vendor / laravel / framework / src / Illuminate / Database / Schema / Grammars / Grammar.php)
Dirk Jan
6
  • Jest to znany problem w Laravel. Więcej informacji na ten temat tutaj .

  • Ta funkcja nie jest obsługiwana w SQLite, zobacz tutaj

  • Również temat, który zawiera szczegółowe omówienie tego problemu

MK
źródło
1
@SimonBengtsson Problem musiał zostać zamknięty lub usunięty.
MK,
5

Według

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

$ table-> onDelete ('set null') powinno działać, być może spróbuj

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

Jeśli są jakieś błędy, również byłoby pomocne

Chris Barrett
źródło
Możesz chcieć wycofać się, ręcznie napisać sql, a następnie przeprowadzić testy i przeprowadzić testy lokalne. Wszystko, co mogę znaleźć, mówi, że powinno działać dev.mysql.com/doc/refman/5.6/en/... , może być problem z generowaniem sql
Chris Barrett
Dzięki! Niestety spowodowało to ten sam problem. Myślę, że jest to coś specyficznego dla SqLite i odwołań cyklicznych.
MK
Plus jeden, ponieważ onDelete ('set null') działa z mysql.
Simon Bengtsson
3

Używając Laravel 4.2 na MySQL 5.5 z InnoDB, działa onDelete ('set null').

Mark Kendall
źródło