Laravel Schema onDelete set null

112

Não consigo descobrir como definir a restrição onDelete adequada em uma tabela no Laravel. (Estou trabalhando com SqLite)

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

Tenho 3 migrações, criando a tabela da galeria:

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

Criando a tabela de imagens:

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

Vinculando a tabela da galeria a uma imagem:

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

Eu não recebo nenhum erro. Além disso, mesmo a opção "cascata" não funciona (apenas na mesa da galeria). Excluir uma galeria exclui todas as fotos. Mas excluir a imagem da capa não irá excluir a galeria (para fins de teste).

Visto que nem mesmo a "cascata" é acionada, "definir nulo" não é o problema.

EDITAR (solução alternativa):

Depois de ler este artigo , mudei um pouco meu esquema. Agora, a tabela de imagens contém uma célula "is_cover", que indica se a imagem é uma capa de seu álbum ou não.

Uma solução para o problema original ainda é muito apreciada!

MK
fonte

Respostas:

317

Se você deseja definir nulo na exclusão:

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

Primeiro, certifique-se de definir o campo de chave estrangeira como anulável:

$table->integer('foreign_id')->unsigned()->nullable();
João
fonte
37
mais para->nullable()
mohsenJsh de
3
Existe alguma documentação do Laravel sobre isso?
Chuck Le Butt
laravel.com/docs/6.x/migrations#foreign-key-constraints não documenta quais opções existem, mas acho que você pode assumir que são os valores padrão do mysql (consulte ../ vendor / laravel / framework / src / Illuminate / Database / Schema / Grammars / Grammar.php)
Dirk
6
  • Este é um problema conhecido no Laravel. Mais informações sobre isso aqui .

  • Este recurso não é compatível com SQLite, veja aqui

  • Também um tópico que mostra detalhadamente este problema

MK
fonte
1
@SimonBengtsson O problema deve ter sido fechado ou excluído.
MK de
5

De acordo com

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

$ table-> onDelete ('set null') deve funcionar antes de tentar

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

Se houver algum erro, também seria útil

Chris Barrett
fonte
Você pode querer reverter, escrever o sql manualmente e então executar e executar testes no local. Tudo que posso encontrar diz que deve funcionar dev.mysql.com/doc/refman/5.6/en/… , pode ser um problema ao gerar o sql
Chris Barrett
Obrigado! Infelizmente, isso resultou no mesmo problema. Acho que é algo específico para referências SqLite e circulares.
MK de
Mais um porque onDelete ('set null') funciona com mysql.
Simon Bengtsson
3

Usando o Laravel 4.2 no MySQL 5.5 com InnoDB, onDelete ('set null') funciona.

Mark Kendall
fonte