146

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!

4

8 回答 8

389

如果要在删除时设置 null:

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

首先确保将外键字段设置为可为空:

$table->integer('foreign_id')->unsigned()->nullable();
于 2014-09-10T12:46:23.547 回答
28

在 laravel 8 中,您可以使用:

$table->foreignId('forign_id')->nullable()->constrained("table_name")->cascadeOnUpdate()->nullOnDelete();

参考

不同的选项在类中声明Illuminate\Database\Schema\ForeignKeyDefinition参见源代码)。

于 2020-12-14T05:20:23.803 回答
6
  • 这是 Laravel 中的一个已知问题。更多关于这里的信息。

  • SQLite 不支持此功能,请参见此处

  • 也是一个对这个问题有详细摊牌的话题

于 2014-01-02T00:40:11.153 回答
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'));

如果有任何错误,也将有所帮助

于 2014-01-01T13:32:25.243 回答
3

在带有 InnoDB 的 MySQL 5.5 上使用 Laravel 4.2,onDelete('set null') 有效。

于 2014-08-26T10:25:28.957 回答
2

在 laravel 8 中你可以这样做。

 $table->foreignId('table_id')->nullable()->constrained()->onDelete('set null');

nullable() 列修饰符必须在 constrained() 和 onDelete('set null') 之前调用

于 2021-03-19T13:28:18.310 回答
0

SQLite 不支持 ALTER TABLE 命令的 ADD CONSTRAINT 变体

SQLite外键在phpunit测试中删除时不设置null

于 2021-04-12T14:22:09.880 回答
0

你也可以使用nullOnDelete()方法。请参阅 laravel 8.x https://laravel.com/docs/8.x/migrations#foreign-key-constraints

$table->foreignId('table_id')->nullable()->constrained()->nullOnDelete();
于 2022-01-07T06:53:12.730 回答