Laravel Eloquent:具有删除功能的参照完整性

时间:2018-12-24 14:53:25

标签: laravel eloquent

我有三个表:beerglasses,标签和beerglasses_tags。一个啤酒杯可以有多个标签。

    Schema::create('beerglasses', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('brewery_id');
        $table->foreign( 'brewery_id' )
            ->references( 'id' )->on( 'breweries' )
            ->onUpdate( 'cascade' )
            ->onDelete( 'cascade' );
        $table->string('beerglass_name');
        $table->timestamps();
    });


    Schema::create('beerglasses_tag', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('beerglass_id')->unsigned();
        $table->foreign('beerglass_id')
                ->references('id')
                ->on('beerglasses')
                ->onUpdate( 'cascade' )
                ->onDelete( 'cascade' );
        $table->integer('tag_id')->unsigned();
        $table->foreign('tag_id')
                ->references('id')
                ->on('tags')
                ->onUpdate( 'cascade' )
                ->onDelete( 'cascade' );
    });

    Schema::create('tags', function (Blueprint $table) {
        $table->increments('id');            
        $table->string('tag_name');
        $table->timestamps();
    });

我有以下条目:

mysql> select id, brewery_id, beerglass_name from beerglasses;
+----+------------+----------------+
| id | brewery_id | beerglass_name |
+----+------------+----------------+
|  4 |          3 | Glass1         |
|  5 |          3 | Glass2         |
+----+------------+----------------+

mysql> select * from beerglasses_tag;
+----+--------------+--------+
| id | beerglass_id | tag_id |
+----+--------------+--------+
|  3 |            4 |      4 |
|  4 |            5 |      3 |
+----+--------------+--------+

 mysql> select id, tag_name from tags;
+----+----------+
| id | tag_name |
+----+----------+
|  3 | Tag 1    |
|  4 | Tag 2    |

这种行为使得我无法删除“啤酒杯”,因为有与之相关的标签。例如。如果我要删除啤酒杯4,它会抱怨无法删除它。猜猜这是因为啤酒杯4与标签4相关联。

在任何时候,我都希望能够删除“啤酒杯”。如果beerglass引用了标签,则应从beerglasses_tag表中删除引用。

接下来,我只想删除数据库中所有啤酒杯未使用的“标签”。

我如何更改架构才能实现这一目标?

1 个答案:

答案 0 :(得分:2)

您使用雄辩的模型关系了吗?您可以提供模型方案吗? 如果确实如此,则需要在删除啤酒杯之前清空/删除关联的标签。

$beerglass->tags->detach()
$beerglass->delete();

,反之亦然。因为在多对多关系中,当您删除一个项目时,相关项目仍会查找该已删除项目,这可能会造成问题。因此,在删除项目之前,我们需要从数据透视表中清除相关项目。对于您的情况,需要确保在删除之前清除与“ Beerglass”链接的数据透视表的条目。