在Laravel中软删除父记录时,如何软删除相关记录?

2022-08-30 17:40:32

我有这个具有以下结构的发票表

id | name | amount | deleted_at
2    iMac   1500   | NULL

和具有以下结构的付款表

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 on Invoice 表可以完美地工作,但其相关记录(付款)仍然存在。如何使用软删除删除它们?


答案 1

Eloquent不提供相关对象的自动删除功能,因此您需要自己编写一些代码。幸运的是,这很简单。

雄辩的模型在模型生命周期的不同阶段触发不同的事件,如创建,创建,删除,删除等 - 你可以在这里阅读更多关于它的信息:http://laravel.com/docs/5.1/eloquent#events。您需要的是一个侦听器,该侦听器将在触发已删除事件时运行 - 然后该侦听器应删除所有相关对象。

您可以在模型的 boot() 方法中注册模型侦听器。侦听器应循环访问要删除的发票的所有付款,并应逐个删除它们。批量删除在这里不起作用,因为它会直接绕过模型事件执行 SQL 查询。

这将解决问题:

class MyModel extends Model {
  protected static function boot() {
    parent::boot();

    static::deleted(function ($invoice) {
      $invoice->payments()->delete();
    });
  }
}

答案 2

您可以采用以下2种方式之一。

最简单的方法是覆盖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();

    });
}

上述方法中的任何一个(但不是两个)都将进入您的模型。另外,我假设您在模型中设置了关系,但是,我不确定您是否允许为一张发票进行多次付款。无论哪种方式,都可能需要将示例中的 更改为您在发票模型中命名的关系。Invoicepayments()

希望这有帮助!


推荐