Skema Laravel onDelete menyetel null

112

Tidak tahu cara menyetel batasan onDelete yang tepat pada tabel di Laravel. (Saya bekerja dengan SqLite)

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

Saya memiliki 3 migrasi, membuat tabel galeri:

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

Membuat tabel gambar:

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

Menautkan tabel galeri ke gambar:

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

Saya tidak menerima kesalahan apapun. Selain itu, bahkan opsi "kaskade" tidak berfungsi (hanya di tabel galeri). Menghapus galeri akan menghapus semua gambar. Tetapi menghapus gambar sampul, tidak akan menghapus galeri (untuk tujuan pengujian).

Karena bahkan "cascade" tidak dipicu, saya "set null" bukanlah masalah.

EDIT (solusi):

Setelah membaca artikel ini, saya sedikit mengubah skema saya. Sekarang, tabel gambar berisi sel "sampul_is", yang menunjukkan apakah gambar ini adalah sampul di albumnya atau bukan.

Solusi untuk masalah asli masih sangat dihargai!

MK
sumber

Jawaban:

318

Jika Anda ingin menyetel null saat hapus:

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

Pertama, pastikan Anda menyetel bidang kunci asing sebagai nullable:

$table->integer('foreign_id')->unsigned()->nullable();
Johan
sumber
37
plus untuk->nullable()
mohsenJsh
3
Apakah ada beberapa dokumentasi Laravel tentang ini?
Chuck Le Butt
laravel.com/docs/6.x/migrations#foreign-key-constraints itu tidak mendokumentasikan opsi apa yang ada, tetapi saya pikir Anda dapat mengasumsikan itu adalah nilai mysql default (lihat ../ vendor / laravel / framework / src / Illuminate / Database / Schema / Grammars / Grammar.php)
Dirk
6
  • Ini adalah masalah yang diketahui di Laravel. Info lebih lanjut tentang ini di sini .

  • Fitur ini tidak didukung di SQLite, lihat di sini

  • Juga topik yang memiliki pertarungan mendetail tentang masalah ini

MK
sumber
1
@SimonBengtsson Masalah ini pasti sudah ditutup atau dihapus.
MK
5

Berdasarkan

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

$ table-> onDelete ('set null') harus bekerja sebelum percobaan

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

Jika ada kesalahan apapun, akan sangat membantu

Chris Barrett
sumber
Anda mungkin ingin memutar kembali, menulis sql dengan tangan dan kemudian memeriksa dan menjalankan pengujian di lokal. Semua yang dapat saya temukan mengatakan bahwa seharusnya berfungsi dev.mysql.com/doc/refman/5.6/en/… , bisa menjadi masalah menghasilkan sql
Chris Barrett
Terima kasih! Sayangnya itu menghasilkan masalah yang sama. Saya pikir itu adalah sesuatu yang spesifik untuk referensi SqLite dan melingkar.
MK
Ditambah satu karena onDelete ('set null') berfungsi dengan mysql.
Simon Bengtsson
3

Menggunakan Laravel 4.2 di MySQL 5.5 dengan InnoDB, onDelete ('set null') berfungsi.

Mark Kendall
sumber