在Laravel 6/7中删除相关模型

时间:2020-08-23 10:40:33

标签: laravel eloquent cascading-deletes

有很多相关问题,但不幸的是我找不到有效的解决方案

我有Laravel模型,删除此模型后我想

  1. 删除一些相关模型
  2. 删除模型时运行自定义SQL查询

我的Laravel的模型类看起来像(您可以看到模型可以具有不同的关系类型)

class ModelA extends Model
{
  public functions modelsB() {
    return $this->hasMany(ModelB:class);
  }

  public functions modelsC() {
    return $this->belongsToMany(ModelC:class);
  }

  // other related models
 
  // place where I am expecting actual deleting is happening
  public static function boot() {
        parent::boot();

        self::deleting(function($modelA) { 

          $modelA->modelsB()->get()->each->delete(); 
         
          foreach($modelA->modelsC as $modelC){
            $modelC->delete();
          }
    });
  }
}

ModelA被删除,但是所有相关数据都保留了,而且我不确定它是否被调用。也许我错过了什么?我应该为ModelA扩展一些课程吗?还是应该将此启动功能放在其他地方?

5 个答案:

答案 0 :(得分:3)

https://laravel.com/docs/7.x/eloquent#events-using-closures呢?像

30         %let ident = 4644968792486317489 ;
31         
32         data _null_ ;
33          numero= put(&ident.,z19.);
34          call symputx('numero',numero);
35         run;

NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
      

36         
37         %put &numero. ;
4644968792486317056

答案 1 :(得分:3)

您是否将其级联到模型B的迁移文件中,如下所示:

$table->foreignId('modelA_id')
    ->onDelete('cascade');
    ->constrained()

onDelete('cascade')是重要的部分,请注意,这是以下内容的简写:

$table->unsignedBigInteger('modelA_id');

$table->foreign('modelA_id')->references('id')
    ->on('modelA')->onDelete('cascade');

这应该为您完成大部分繁重的工作,您可以在Laravel Docs Migrations

中找到更多信息。

如果您不喜欢这种方法,而是希望使用基于事件的方法,请尝试在您的ModelA类中这样做:

protected static function booted()
{
    static::deleted(function ($modelA) {
        $modelA->modelsB()->delete();
        // ...
    });
}

答案 2 :(得分:2)

您尝试使用static而不是self

documentation中,Laravel建议在绑定事件或观察者时使用static关键字

答案 3 :(得分:2)

如果您试图从模型本身内部删除相关模型。您只需要调用$this->reletedModel()->delete();,实际上就不需要foreach()循环。

鉴于您有一个函数定义了带有以下声明的关系。

public function relatedModel()
{
    return $this->hasOne(RelatedModel::class);
    //OR
    //return $this->hasMany(RelatedModel::class);
}

/** Function to delete related models */
public function deleteRelatedModels()
{
    return $this->relatedModel()->delete();
}

答案 4 :(得分:2)

我建议使用Observers来监听ModelA删除的事件。

  1. 运行php artisan make:observer ModelAObserver --model=ModelA
  2. AppServiceProvider的{​​{1}}中添加boot()
  3. 现在在ModelA::observe(ModelAObserver::class);中的ModelAObserver方法中,您将删除关联的模型并执行自定义SQL查询。
deleted()

您还需要在/** * Handle the ModelA "deleted" event. * * @param \App\ModelA $modelA * @return void */ public function deleted(ModelA $modelA) { // delete associated models $modelA->modelsB()->delete(); $modelA->modelsC()->delete() ... // perform custom SQL queries ... } 上调用delete的任何地方添加数据库事务,以确保操作是否完全完成。

ModelA