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

use*_*278 14 php soft-delete laravel eloquent laravel-5

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

id | name | amount | deleted_at
2    iMac   1500   | NULL
Run Code Online (Sandbox Code Playgroud)

以及具有以下结构的付款表

id | invoice_id | amount | deleted_at
2    2            1000   | NULL
Run Code Online (Sandbox Code Playgroud)

发票模型

class Invoice extends Model {

    use SoftDeletes;

}
Run Code Online (Sandbox Code Playgroud)

这是删除发票的代码

public function cance(Request $request,$id)
{
    $record = Invoice::findOrFail($id);
    $record->delete();
    return response()->json([
        'success' => 'OK',
    ]);
}
Run Code Online (Sandbox Code Playgroud)

付款模式

class Payment extends Model {

    use SoftDeletes;

}
Run Code Online (Sandbox Code Playgroud)

Invoice表上的softDelete工作正常,但其相关记录(付款)仍然存在.如何使用softDelete删除它们?

jed*_*ylo 15

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();
    });
  }
}
Run Code Online (Sandbox Code Playgroud)


Rwd*_*Rwd 9

您可以使用此方法中的一种.

最简单的方法是覆盖Eloquents delete()方法并包括相关模型,例如:

public function delete()
{
    $this->payments()->delete();
    return parent::delete();
} 
Run Code Online (Sandbox Code Playgroud)

上面的方法应该可以找到,但它似乎有点脏,我会说它不是社区中的首选方法.

更清洁的方式(IMO)将利用Eloquents事件,例如:

public static function boot()
{
    parent::boot();

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

    });
}
Run Code Online (Sandbox Code Playgroud)

上述方法中的任何一个(但不是两个)都会出现在您的Invoice模型中.此外,我假设您在模型中设置了您的关系,但是,我不确定您是否允许为一张发票多次付款.无论哪种方式,您可能需要payments()将示例中的内容更改为您在发票模型中命名关系的任何内容.

希望这可以帮助!


Sal*_*dor 9

我知道您很久以前就问过这个问题,但是我发现此程序包非常简单明了。

或者您也可以使用此包,它也很有用。

请记住,根据您的laravel版本安装正确的版本。

您必须通过composer安装它:

 composer require askedio/laravel5-soft-cascade ^version
Run Code Online (Sandbox Code Playgroud)

在第二个包中:

 composer require iatstuti/laravel-cascade-soft-deletes
Run Code Online (Sandbox Code Playgroud)

在您的config / app.php中注册服务提供商。

您可以在GitHub页面上阅读文档。

如果删除记录,则此程序包将识别其所有子项,并对其进行软删除。

如果您的子模型中还有其他关系,请在该模型中也使用它的特征。它比手动完成要容易得多。

第二个软件包的好处是删除了模型的孙代。在某些情况下,我说这是一种更好的方法。