Laravel Eloquent ORM - 删除行及其所有子关系,使用事件删除

9

我有三个相互关联的模型,一个对多个:

国家

class Country extends Model
{
    protected $fillable=['name','sort'];
    public $timestamps=false;

    public function region(){
        return $this->hasMany('App\Models\Region');
    }
}

地区

class Region extends Model
{

    protected $fillable=['country_id','name','sort'];
    public  $timestamps=false;

    public function country()
    {
        return $this->belongsTo('App\Models\Country');
    }

    public function city()
    {
        return $this->hasMany('App\Models\City');
    }
}

城市

class City extends Model
{
    protected $table='cities';
    protected $fillable=['region_id','name','sort'];
    public  $timestamps=false;

    public function region()
    {
        return $this->belongsTo('App\Models\Region');
    }
}

当我们自动删除一个国家时,需要删除其所有子项目关系,也就是删除该国家下的所有区域和城市。

我的做法是:

国家模型

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

        static::deleting(function($country) {
            //remove related rows region and city

            // need an alternative variation of this code
            $country->region()->city()->delete();//not working
            $country->region()->delete();

            return true;
        });
    }
}

模型区域

public  static function boot() {
        parent::boot();
        // this event do not working, when delete a parent(country)
        static::deleting(function($region) {
            dd($region);
            //remove related rows city
            $region->city()->delete();
            return true;
        });
    }
}

请不要提供级联删除数据库的选项

更新

我找到了答案

使用闭包来构建查询器,以删除相关模型

国家模型

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

        static::deleting(function($country) {
            //remove related rows region and city
            $country->region->each(function($region) {
                $region->city()->delete();
            });
            $country->region()->delete();//
            return true;
        });
    }

Laravel Eloquent ORM - 删除行和所有内部关系


你尝试过 $this->region()->city()->delete(); 吗? - Kalhan.Toress
@K.Toress尝试调用city()方法,但出现了BadMethodCallException: Illuminate\Database\Query\Builder类中未定义该方法。 - Kamol Hakimbaev
你在删除Model Country中的区域之前,尝试过先删除城市吗? - Björn
@Björn,如何在模型Country中执行以下操作:$country->region()->city()->delete(); $country->region()->delete();出现BadMethodCallException: Call to undefined method Illuminate\Database\Query\Builder::city()。 - Kamol Hakimbaev
你可以在迁移中为列设置->onDelete('cascade') - Mahbod Ahmadi
2个回答

3

简述:

$model->related_model 将返回相关模型。
$model->related_model() 将返回关系对象。

您可以使用 $model->related_model->delete()$model->related_model()->get()->delete() 访问模型的 delete() 方法。

另一种处理相关(或子)模型删除的方法是在编写迁移时使用外键约束,请参见 https://laravel.com/docs/master/migrations#foreign-key-constraints


2
在集合上不能调用delete()。 - Kamol Hakimbaev
在这种情况下,只需循环遍历集合中的所有模型并逐个删除它们,或者使用查询构建器删除方法。 - Shaz MJ

1

我认为你可以在父对象的删除函数中完成这个操作:

public function destroy_parent($id)
{
    $parent = PARENT::find($id);
    foreach ($parent->childs as $child){
            $child->delete();
    }
    $parent->delete();
    return redirect(...);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接