【问题标题】:Laravel Schema onDelete set nullLaravel Schema onDelete 设置为空
【发布时间】:2014-01-19 01:57:55
【问题描述】:

无法弄清楚如何在 Laravel 中的表上设置正确的 onDelete 约束。 (我正在使用 SqlLite)

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

我有 3 个迁移,正在创建库表:

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

创建图片表:

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

将图库表格链接到图片:

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

我没有收到任何错误。此外,即使“级联”选项也不起作用(仅在画廊表上)。删除图库会删除所有图片。但删除封面图片,不会删除图库(用于测试目的)。

由于连“级联”都没有触发,所以我“置空”不是问题。

编辑(解决方法):

阅读此article 后,我稍微更改了我的架构。现在,图片表包含一个“is_cover”单元格,指示这张图片是否是其相册的封面。

仍然非常感谢原始问题的解决方案!

【问题讨论】:

    标签: php laravel laravel-migrations


    【解决方案1】:

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

    $table->foreignId('table_id')->nullable()->constrained()->nullOnDelete();
    

    【讨论】:

      【解决方案2】:

      在 laravel 8 中你可以使用:

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

      Reference

      不同的选项在类Illuminate\Database\Schema\ForeignKeyDefinition (see source) 中声明。

      【讨论】:

      • 用 Laravel 7 测试,也可以在那里工作。
      【解决方案3】:

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

      SQLite foreign key dont set null on delete in phpunit test

      【讨论】:

        【解决方案4】:

        在 laravel 8 中你可以这样做。

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

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

        【讨论】:

          【解决方案5】:

          如果要在删除时设置 null:

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

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

          $table->integer('foreign_id')->unsigned()->nullable();
          

          【讨论】:

          • 加号->nullable()
          • 这有一些 Laravel 文档吗?
          • laravel.com/docs/6.x/migrations#foreign-key-constraints 它没有记录有哪些选项,但我认为您可以假设它是默认的 mysql 值(请参阅../ vendor / laravel / framework / src / Illuminate / Database / Schema / Grammars / Grammar.php
          【解决方案6】:
          • 这是 Laravel 中的一个已知问题。有关此here 的更多信息。

          • SQLite 不支持此功能,请参阅here

          • 还有一个topic对此问题有详细的摊牌

          【讨论】:

          • @SimonBengtsson 该问题必须已关闭或删除。
          【解决方案7】:

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

          【讨论】:

            【解决方案8】:

            根据

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

            $table->onDelete('set null') 应该可以尝试一下

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

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

            【讨论】:

            • 您可能想要回滚,手动写出 sql,然后在本地执行和运行测试。我能找到的一切都说应该工作dev.mysql.com/doc/refman/5.6/en/…,可能是生成sql的问题
            • 谢谢!不幸的是,它导致了同样的问题。我认为这是 SqlLite 和循环引用所特有的。
            • 加一,因为 onDelete('set null') 适用于 mysql。
            猜你喜欢
            • 2019-01-02
            • 1970-01-01
            • 1970-01-01
            • 2021-10-09
            • 2021-09-30
            • 2018-12-07
            • 1970-01-01
            • 1970-01-01
            • 2019-10-01
            相关资源
            最近更新 更多