软删除Laravel中父记录时,如何软删除相关记录?
How to soft delete related records when soft deleting a parent record in Laravel?
我有这张发票table,它具有以下结构
id | name | amount | deleted_at
2 iMac 1500 | NULL
和具有以下结构的付款 table
id | invoice_id | amount | deleted_at
2 2 1000 | NULL
发票模型
class Invoice extends Model {
use SoftDeletes;
}
这是删除发票的代码
public function cance(Request $request,$id)
{
$record = Invoice::findOrFail($id);
$record->delete();
return response()->json([
'success' => 'OK',
]);
}
支付模式
class Payment extends Model {
use SoftDeletes;
}
发票上的 softDelete table 完美运行,但其相关记录(付款)仍然 exists.How 我要使用 softDelete 删除它们吗?
您可以选择以下两种方式之一。
最简单的方法是覆盖 Eloquents delete()
方法并包括相关模型,例如:
public function delete()
{
$this->payments()->delete();
return parent::delete();
}
上面的方法应该可以找到,但它看起来有点脏,我想说这不是社区内的首选方法。
更简洁的方法 (IMO) 是利用 Eloquents 事件,例如:
public static function boot()
{
parent::boot();
static::deleting(function($invoice) {
$invoice->payments()->delete();
});
}
上述方法中的任何一种(但不是两种)都可以用于您的 Invoice
模型。
另外,我假设您在模型中建立了关系,但是,我不确定您是否允许一张发票多次付款。无论哪种方式,您都可能需要将示例中的 payments()
更改为您在发票模型中为关系命名的任何内容。
希望对您有所帮助!
Eloquent 不提供自动删除相关对象,因此您需要自己编写一些代码。幸运的是,这很简单。
Eloquent models 在模型生命周期的不同阶段触发不同的事件,例如创建、创建、删除、删除等 - 您可以在这里阅读更多相关信息:http://laravel.com/docs/5.1/eloquent#events。您需要的是一个监听器,它会在触发 deleted 事件时 运行 - 然后这个监听器应该删除所有相关对象。
您可以在模型的 boot() 方法中注册模型侦听器。侦听器应遍历要删除的发票的所有付款,并应将其一一删除。批量删除在这里不起作用,因为它会绕过模型事件直接执行 SQL 查询。
这样做就可以了:
class MyModel extends Model {
protected static function boot() {
parent::boot();
static::deleted(function ($invoice) {
$invoice->payments()->delete();
});
}
}
我知道你很久以前就问过这个问题,但我发现 this package 非常简单明了。
或者你可以使用this package它也很有用。
记住根据您的laravel版本安装正确的版本。
您必须通过 composer 安装它:
composer require askedio/laravel5-soft-cascade ^version
在第二个包中:
composer require iatstuti/laravel-cascade-soft-deletes
在您的 config/app.php.
中注册服务提供商
您可以阅读 GitHub 页面上的文档。
如果您删除一条记录,此包会识别其所有子项并同时软删除它们。
如果您的子模型中有其他关系,请在该模型中也使用它的特征。它比手动操作容易得多。
第二个包有删除模型孙子的好处。在某些情况下,我认为这是一种更好的方法。
如果您的数据库关系不超过一层,那么您可以简单地使用 Laravel 事件来处理您在模型boot()
方法如下:
<?php
//...
protected static boot() {
parent::boot();
static::deleting(function($invoice) {
$invoice->payments()->delete();
});
}
但是,如果您的结构比一层更深,您将不得不调整那段代码。
例如,假设您不想删除发票的付款,而是要删除给定用户的整个付款历史记录。
<?php
// ...
class Invoice extends Model
{
// ...
/**
* Holds the methods names of Eloquent Relations
* to fall on delete cascade or on restoring
*
* @var array
*/
protected static $relations_to_cascade = ['payments'];
protected static boot()
{
parent::boot();
static::deleting(function($resource) {
foreach (static::$relations_to_cascade as $relation) {
foreach ($resource->{$relation}()->get() as $item) {
$item->delete();
}
}
});
static::restoring(function($resource) {
foreach (static::$relations_to_cascade as $relation) {
foreach ($resource->{$relation}()->get() as $item) {
$item->withTrashed()->restore();
}
}
});
}
public function payments()
{
return $this->hasMany(Payment::class);
}
}
<?php
// ...
class User extends Model
{
// ...
/**
* Holds the methods names of Eloquent Relations
* to fall on delete cascade or on restoring
*
* @var array
*/
protected static $relations_to_cascade = ['invoices'];
protected static boot()
{
parent::boot();
static::deleting(function($resource) {
foreach (static::$relations_to_cascade as $relation) {
foreach ($resource->{$relation}()->get() as $item) {
$item->delete();
}
}
});
static::restoring(function($resource) {
foreach (static::$relations_to_cascade as $relation) {
foreach ($resource->{$relation}()->get() as $item) {
$item->withTrashed()->restore();
}
}
});
}
public function invoices()
{
return $this->hasMany(Invoice::class);
}
}
这种范式确保 Laravel 跟随兔子洞,无论它有多深。
我有这张发票table,它具有以下结构
id | name | amount | deleted_at
2 iMac 1500 | NULL
和具有以下结构的付款 table
id | invoice_id | amount | deleted_at
2 2 1000 | NULL
发票模型
class Invoice extends Model {
use SoftDeletes;
}
这是删除发票的代码
public function cance(Request $request,$id)
{
$record = Invoice::findOrFail($id);
$record->delete();
return response()->json([
'success' => 'OK',
]);
}
支付模式
class Payment extends Model {
use SoftDeletes;
}
发票上的 softDelete table 完美运行,但其相关记录(付款)仍然 exists.How 我要使用 softDelete 删除它们吗?
您可以选择以下两种方式之一。
最简单的方法是覆盖 Eloquents delete()
方法并包括相关模型,例如:
public function delete()
{
$this->payments()->delete();
return parent::delete();
}
上面的方法应该可以找到,但它看起来有点脏,我想说这不是社区内的首选方法。
更简洁的方法 (IMO) 是利用 Eloquents 事件,例如:
public static function boot()
{
parent::boot();
static::deleting(function($invoice) {
$invoice->payments()->delete();
});
}
上述方法中的任何一种(但不是两种)都可以用于您的 Invoice
模型。
另外,我假设您在模型中建立了关系,但是,我不确定您是否允许一张发票多次付款。无论哪种方式,您都可能需要将示例中的 payments()
更改为您在发票模型中为关系命名的任何内容。
希望对您有所帮助!
Eloquent 不提供自动删除相关对象,因此您需要自己编写一些代码。幸运的是,这很简单。
Eloquent models 在模型生命周期的不同阶段触发不同的事件,例如创建、创建、删除、删除等 - 您可以在这里阅读更多相关信息:http://laravel.com/docs/5.1/eloquent#events。您需要的是一个监听器,它会在触发 deleted 事件时 运行 - 然后这个监听器应该删除所有相关对象。
您可以在模型的 boot() 方法中注册模型侦听器。侦听器应遍历要删除的发票的所有付款,并应将其一一删除。批量删除在这里不起作用,因为它会绕过模型事件直接执行 SQL 查询。
这样做就可以了:
class MyModel extends Model {
protected static function boot() {
parent::boot();
static::deleted(function ($invoice) {
$invoice->payments()->delete();
});
}
}
我知道你很久以前就问过这个问题,但我发现 this package 非常简单明了。
或者你可以使用this package它也很有用。
记住根据您的laravel版本安装正确的版本。
您必须通过 composer 安装它:
composer require askedio/laravel5-soft-cascade ^version
在第二个包中:
composer require iatstuti/laravel-cascade-soft-deletes
在您的 config/app.php.
中注册服务提供商您可以阅读 GitHub 页面上的文档。
如果您删除一条记录,此包会识别其所有子项并同时软删除它们。
如果您的子模型中有其他关系,请在该模型中也使用它的特征。它比手动操作容易得多。
第二个包有删除模型孙子的好处。在某些情况下,我认为这是一种更好的方法。
如果您的数据库关系不超过一层,那么您可以简单地使用 Laravel 事件来处理您在模型boot()
方法如下:
<?php
//...
protected static boot() {
parent::boot();
static::deleting(function($invoice) {
$invoice->payments()->delete();
});
}
但是,如果您的结构比一层更深,您将不得不调整那段代码。
例如,假设您不想删除发票的付款,而是要删除给定用户的整个付款历史记录。
<?php
// ...
class Invoice extends Model
{
// ...
/**
* Holds the methods names of Eloquent Relations
* to fall on delete cascade or on restoring
*
* @var array
*/
protected static $relations_to_cascade = ['payments'];
protected static boot()
{
parent::boot();
static::deleting(function($resource) {
foreach (static::$relations_to_cascade as $relation) {
foreach ($resource->{$relation}()->get() as $item) {
$item->delete();
}
}
});
static::restoring(function($resource) {
foreach (static::$relations_to_cascade as $relation) {
foreach ($resource->{$relation}()->get() as $item) {
$item->withTrashed()->restore();
}
}
});
}
public function payments()
{
return $this->hasMany(Payment::class);
}
}
<?php
// ...
class User extends Model
{
// ...
/**
* Holds the methods names of Eloquent Relations
* to fall on delete cascade or on restoring
*
* @var array
*/
protected static $relations_to_cascade = ['invoices'];
protected static boot()
{
parent::boot();
static::deleting(function($resource) {
foreach (static::$relations_to_cascade as $relation) {
foreach ($resource->{$relation}()->get() as $item) {
$item->delete();
}
}
});
static::restoring(function($resource) {
foreach (static::$relations_to_cascade as $relation) {
foreach ($resource->{$relation}()->get() as $item) {
$item->withTrashed()->restore();
}
}
});
}
public function invoices()
{
return $this->hasMany(Invoice::class);
}
}
这种范式确保 Laravel 跟随兔子洞,无论它有多深。