Laravel Schema onDelete устанавливает значение null

112

Не могу понять, как правильно установить ограничение onDelete для таблицы в Laravel. (Я работаю с SqLite)

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

У меня есть 3 миграции, создающие таблицу галереи:

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

Создание таблицы изображений:

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

Связывание таблицы галереи с изображением:

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

Ошибок не получаю. Также не работает даже опция "каскад" (только на столе галереи). При удалении галереи удаляются все изображения. Но при удалении обложки галерея не удаляется (в тестовых целях).

Поскольку даже «каскад» не запускается, я не «установил ноль».

РЕДАКТИРОВАТЬ (обходной путь):

После прочтения этой статьи я немного изменил свою схему. Теперь таблица изображений содержит ячейку «is_cover», которая указывает, является ли это изображение обложкой в ​​его альбоме или нет.

Решение исходной проблемы все еще очень ценится!

МК
источник

Ответы:

319

Если вы хотите установить null при удалении:

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

Сначала убедитесь, что вы установили поле внешнего ключа как допускающее значение NULL:

$table->integer('foreign_id')->unsigned()->nullable();
Йохан
источник
37
плюс для->nullable()
mohsenJsh
3
Есть ли по этому поводу документация Laravel?
Чак Ле Батт
laravel.com/docs/6.x/migrations#foreign-key-constraints он не документирует, какие есть варианты, но я думаю, вы можете предположить, что это значения mysql по умолчанию (см. ../ vendor / laravel / framework / src / Illuminate / Database / Schema / Grammars / Grammar.php)
Дирк,
6
  • Это известная проблема в Laravel. Подробнее об этом здесь .

  • Эта функция не поддерживается в SQLite, см. Здесь

  • Также тема , в которой подробно раскрывается эта проблема

МК
источник
1
@SimonBengtsson Вопрос должен быть закрыт или удален.
MK
5

В соответствии с

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

$ table-> onDelete ('set null') должен работать, возможно, попробуйте

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

Если есть какие-то ошибки, тоже будет полезно

Крис Барретт
источник
Возможно, вам захочется откатиться, вручную написать sql, а затем выполнить и запустить тесты на локальном компьютере. Все, что я могу найти, говорит о том, что должно работать dev.mysql.com/doc/refman/5.6/en/… , может быть проблема с генерацией sql
Крис Барретт
Спасибо! К сожалению, это привело к той же проблеме. Я думаю, что это что-то особенное для SqLite и циклических ссылок.
MK
Плюс один, потому что onDelete ('set null') работает с mysql.
Саймон Бенгтссон
3

При использовании Laravel 4.2 в MySQL 5.5 с InnoDB работает onDelete ('set null').

Марк Кендалл
источник