sofa / eloquent-cascade
Laravel Eloquent ORM 的级联删除。
资助包维护!
jarektkaczyk
softonsofa.com
Requires
- php: >=7.2.5
- illuminate/database: >=6.20.14
README
为 Eloquent ORM (Laravel 5.0+) 提供级联(软/硬)删除功能。
为什么使用这个包? 已经有几个包提供了 Eloquent 的级联删除功能,但没有一个与查询构建器兼容。在这里,您将获得对 $model->delete()
和 $query->delete()
的支持,以及 $model->forceDelete()
。
安装
包与 Laravel (Illuminate) 版本兼容,以便您轻松选择合适的版本
Laravel / Illuminate 5.2+
composer require sofa/eloquent-cascade:"~5.2"
Laravel / Illuminate 5.0/5.1
composer require sofa/eloquent-cascade:"~5.1"
用法
在您的模型中使用提供的 CascadeDeletes
特性,并定义要级联删除的关系。相关模型将自动且适当地被删除,即 硬删除
或 软删除
,具体取决于相关模型设置和使用的删除方法。
tldr;
$model->delete()
&$query->delete()
无软删除- 使用软删除时确保特性顺序:
use SoftDeletes, CascadeDeletes
$model->delete()
&$query->delete()
带软删除$model->forceDelete()
但是$query->forceDelete()
将不会工作
简单
<?php namespace App; use Sofa\EloquentCascade\CascadeDeletes; class Product extends \Illuminate\Database\Eloquent\Model { use CascadeDeletes; protected $deletesWith = ['types', 'photos'];
-
在模型上调用
delete()
root@578687bd11c8:/var/www/html# php artisan tinker Psy Shell v0.7.2 (PHP 7.0.3 — cli) by Justin Hileman >>> DB::enableQueryLog() => null >>> App\Product::find(200)->delete() => true >>> DB::getQueryLog() => [ [ "query" => "select * from `products` where `products`.`id` = ? limit 1", "bindings" => [200], ], [ "query" => "delete from `products` where `id` = ?", "bindings" => [200], ], [ "query" => "delete from `product_types` where `product_types`.`product_id` = ? and `product_types`.`product_id` is not null", "bindings" => [200], ], [ "query" => "delete from `photos` where `photos`.`product_id` = ? and `photos`.`product_id` is not null", "bindings" => [200], ], ]
-
在 Eloquent 查询
Builder
上调用delete()
>>> App\Product::whereIn('id', [202, 203])->delete() => 2 >>> DB::getQueryLog() => [ [ "query" => "select * from `products` where `id` in (?, ?)", "bindings" => [202, 203], ], [ "query" => "delete from `product_types` where `product_types`.`product_id` in (?, ?)", "bindings" => [202, 203], ], [ "query" => "update `photos` set `deleted_at` = ?, `updated_at` = ? where `photos`.`product_id` in (?, ?) and `photos`.`deleted_at` is null", "bindings" => [ "2016-05-31 09:44:41", "2016-05-31 09:44:41", 202, 203, ], ], [ "query" => "delete from `products` where `id` in (?, ?)", "bindings" => [202, 203], ], ]
与 SoftDeletes
一起使用
注意 特性的使用顺序很重要,因此请确保您在 CascadeDeletes
之前使用 SoftDeletes
。
<?php namespace App; use Sofa\EloquentCascade\CascadeDeletes; use Illuminate\Database\Eloquent\SoftDeletes; class Product extends \Illuminate\Database\Eloquent\Model { use SoftDeletes, CascadeDeletes; // related Photo model uses SoftDeletes as well, but Type does not protected $deletesWith = ['types', 'photos'];
-
带软删除的级联 - 每个使用
SoftDeletes
的模型都会软删除,其他则硬删除>>> App\Product::whereIn('id', [300, 301])->delete() => 2 >>> DB::getQueryLog() => [ [ "query" => "select * from `products` where `id` in (?, ?) and `products`.`deleted_at` is null", "bindings" => [300, 301], ], [ "query" => "delete from `product_types` where `product_types`.`product_id` in (?, ?)", "bindings" => [300, 301], ], [ "query" => "update `photos` set `deleted_at` = ?, `updated_at` = ? where `photos`.`product_id` in (?, ?) and `photos`.`deleted_at` is null", "bindings" => [ "2016-05-31 09:52:30", "2016-05-31 09:52:30", 300, 301, ], ], [ "query" => "update `products` set `deleted_at` = ?, `updated_at` = ? where `id` in (?, ?) and `products`.`deleted_at` is null", "bindings" => [ "2016-05-31 09:52:30", "2016-05-31 09:52:30", 300, 301, ], ], ]
-
在模型上调用
forceDelete()
会对所有关系进行硬删除(注意 由于 Laravel 核心中forceDelete
的当前实现,它不会在 Builder 上工作)>>> App\Product::find(302)->forceDelete() => true >>> DB::getQueryLog() => [ [ "query" => "select * from `products` where `products`.`id` = ? and `products`.`deleted_at` is null limit 1", "bindings" => [302], ], [ "query" => "delete from `products` where `id` = ?", "bindings" => [302], ], [ "query" => "delete from `product_types` where `product_types`.`product_id` = ? and `product_types`.`product_id` is not null", "bindings" => [302], ], [ "query" => "delete from `photos` where `photos`.`product_id` = ? and `photos`.`product_id` is not null", "bindings" => [302], ], ]
待办事项
- 级联恢复软删除的模型
- 分离 m-m 关系 / 删除相关
- 添加 SET NULL 和 RESTRICT 选项 (?)
贡献
欢迎所有贡献,PR 必须遵守 PSR-2 规范。
变更日志
v6 <- v5.x
- 现在恢复将只对与父模型一起删除的子模型进行级联,而不是之前。也就是说,如果某些子模型在父模型删除之前已经软删除,那么在父模型恢复时,这些子模型不会被恢复。这是预期的行为。
- 这要求当在查询构建器上调用恢复而不是单个模型(
$query->restore()
与$model->restore()
)时,它将运行 N 个查询,每个恢复的模型一个。