shiftonelabs/laravel-cascade-deletes

为 Eloquent 模型添加应用程序级级联删除。

2.0.1 2024-09-22 15:31 UTC

This package is auto-updated.

Last update: 2024-09-22 15:41:02 UTC


README

Latest Version on Packagist Software License Build Status Coverage Status Quality Score Total Downloads

这个 Laravel/Lumen 包为 Laravel 的 Eloquent ORM 提供了应用程序级别的级联删除。当在数据存储级别无法或不能强制执行引用完整性时,此包使您能够在应用程序级别轻松设置此功能。

例如,如果您使用 SoftDeletes 或使用多态关系,这些都是数据库中的外键无法强制执行引用完整性,并且应用程序需要介入的情况。此包可以帮助您。

版本

此包已在 Laravel 4.1 至 Laravel 11.x 上进行了测试,尽管它可能在发布新版本时继续工作。本节将更新以反映已测试的版本。

本说明已更新以显示最新支持的版本(9.x - 11.x)的信息。对于 Laravel 4.1 至 Laravel 8.x,请查看 1.x 分支。

安装

通过 Composer

composer require shiftonelabs/laravel-cascade-deletes

使用方法

启用级联删除有两种方法。一种是

  • 更新您的 Model 以扩展 \ShiftOneLabs\LaravelCascadeDeletes\CascadesDeletesModel,或者
  • 更新您的 Model 以使用 \ShiftOneLabs\LaravelCascadeDeletes\CascadesDeletes 特性。

完成后,在 Model 上定义 $cascadeDeletes 属性。该 $cascadeDeletes 属性应设置为要删除的父记录时也应删除的关系数组。

现在,当删除父记录时,将删除定义的子记录。此外,如果子记录也定义了级联删除,则删除将级联到子记录的相关记录,依此类推。这将一直持续到所有子记录、孙记录、曾孙记录等都被删除。

此外,所有级联删除都在事务中执行。这使得删除成为“全有或全无”事件。如果由于任何原因无法删除子记录,则事务将回滚且不会删除任何记录。导致子记录无法删除的 Exception 将冒泡到 delete() 最初开始的地方,需要捕获和处理。**

代码示例

用户模型

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use ShiftOneLabs\LaravelCascadeDeletes\CascadesDeletes;

class User extends Model {
    use CascadesDeletes;

    protected $cascadeDeletes = ['posts', 'profile'];

    public function posts()
    {
        return $this->hasMany(Post::class);
    }

    public function profile()
    {
        return $this->hasOne(Profile::class);
    }

    public function type()
    {
        return $this->belongsTo(Type::class);
    }
}

配置文件模型

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use ShiftOneLabs\LaravelCascadeDeletes\CascadesDeletes;

class Profile extends Model {
    use CascadesDeletes;

    protected $cascadeDeletes = ['addresses'];

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function addresses()
    {
        return $this->morphMany(Address::class, 'addressable');
    }
}

在上面的示例中,已将 CascadesDeletes 特性添加到 User 模型以启用级联删除。由于用户被认为是帖子和相关配置文件的父母,因此已将这些关系添加到 $cascadeDeletes 属性中。此外,已将 Profile 模型设置为删除其相关地址记录。

在这种设置下,当删除用户记录时,将删除所有相关的帖子和相关配置文件记录。删除还会级联到配置文件记录,并将删除与配置文件相关的所有地址。

如果帖子、配置文件或地址中的任何一个无法删除,则事务将回滚且不会删除任何记录,包括原始用户记录。**

** 仅当使用的数据库实际支持事务时,才会发生事务回滚。大多数数据库都支持事务,但有些不支持。例如,MySQL 的 InnoDB 引擎支持事务,但 MyISAM 引擎不支持。

SoftDeletes

此包还适用于设置为 SoftDeletes 的模型。

当使用 SoftDeletes 时,所使用的删除方法将级联到其他删除操作。也就是说,如果您 delete() 一条记录,所有子记录也将使用 delete();如果您 forceDelete() 一条记录,所有子记录也将使用 forceDelete()

删除操作也会跨越软删除和硬删除的边界。在上面的代码示例中,User 记录被设置为软删除,而 Profile 记录没有被设置为软删除,那么当一个用户被删除时,User 记录会被软删除,而子 Profile 记录会被硬删除,反之亦然。

注意

  • 此包中的功能是通过 Model 上的 deleting 事件提供的。因此,为了使级联删除生效,必须在模型实例上调用 delete()。如果通过查询构建器执行删除操作,则不会进行级联删除。例如,App\User::where('active', 0)->delete(); 只会删除那些用户记录,不会执行任何级联删除,因为 delete() 是在查询构建器上执行的,而不是在模型实例上。

  • 不要将 BelongsTo 关系添加到 $cascadeDeletes 数组中。这会导致 LogicException 异常,并且不会删除任何记录。这是因为在 BelongsTo 中,通常表示子记录,并且通常没有从子记录删除父记录的意义。

贡献

欢迎贡献。请参阅 CONTRIBUTING 以获取详细信息。

安全

如果您发现任何与安全相关的问题,请通过电子邮件 patrick@shiftonelabs.com 而不是使用问题跟踪器。

致谢

许可

MIT 许可证 (MIT)。有关更多信息,请参阅 许可文件