Laravel Schema onDelete set null

PhpLaravelLaravel Migrations

Php 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();

Reference

The different options are declared in class Illuminate\Database\Schema\ForeignKeyDefinition (see source).

Solution 3 - Php

  • This is a known issue in Laravel. More info about this here.

  • This feature is not supported in SQLite, see here

  • Also a topic that has a detailed showdown of this problem

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

SQLite foreign key dont set null on delete in phpunit test

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionM KView Question on Stackoverflow
Solution 1 - PhpJohanView Answer on Stackoverflow
Solution 2 - PhpAyman ElshehawyView Answer on Stackoverflow
Solution 3 - PhpM KView Answer on Stackoverflow
Solution 4 - PhpChris BarrettView Answer on Stackoverflow
Solution 5 - PhpMark KendallView Answer on Stackoverflow
Solution 6 - PhpAli Akbar AfridiView Answer on Stackoverflow
Solution 7 - PhpAmirRezaM75View Answer on Stackoverflow
Solution 8 - PhpNeeraj TangariyaView Answer on Stackoverflow