Laravel Schema onDelete set null
PhpLaravelLaravel MigrationsPhp Problem Overview
Can't figure out how to set proper onDelete constraint on a table in Laravel. (I'm working with SqLite)
$table->...->onDelete('cascade'); // works
$table->...->onDelete('null || set null'); // neither of them work
I have 3 migrations, creating the gallery table:
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';
});
Creating the pictures table:
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';
});
Linking gallery table to a picture:
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
});
I do not receive any errors. Also, even the "cascade" option doesn't work (only on the gallery table). Deleting a gallery deletes all pictures. But deleting the cover picture, wont delete the gallery (for test purposes).
Since even the "cascade" is not triggered, I "set null" is not the problem.
EDIT (workaround):
After reading this article I've changed my schema a bit. Now, the pictures table contains an "is_cover" cell, that indicates whether this picture is a cover on its album or not.
A solution to the original problem is still highly appreciated!
Php Solutions
Solution 1 - Php
If you want to set null on delete:
$table->...->onDelete('set null');
First make sure you set the foreign key field as nullable:
$table->integer('foreign_id')->unsigned()->nullable();
Solution 2 - Php
In laravel 8 you can use:
$table->foreignId('forign_id')->nullable()->constrained("table_name")->cascadeOnUpdate()->nullOnDelete();
The different options are declared in class Illuminate\Database\Schema\ForeignKeyDefinition
(see source).
Solution 3 - Php
Solution 4 - Php
According to
http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html
$table->onDelete('set null') should work prehaps try
$table->...->onDelete(DB::raw('set null'));
If there are any errors, would also be helpful
Solution 5 - Php
Using Laravel 4.2 on MySQL 5.5 with InnoDB, onDelete('set null') works.
Solution 6 - Php
in laravel 8 you can do it like this.
$table->foreignId('table_id')->nullable()->constrained()->onDelete('set null');
nullable() column modifiers must be called before constrained() and onDelete('set null')
Solution 7 - Php
SQLite doesn't support the ADD CONSTRAINT variant of the ALTER TABLE command
Solution 8 - Php
you can use nullOnDelete()
method as well. See laravel 8.x https://laravel.com/docs/8.x/migrations#foreign-key-constraints
$table->foreignId('table_id')->nullable()->constrained()->nullOnDelete();