猿问

我的错误在哪里?无法删除或更新父行:外键约束失败

我正在尝试从我的数据库中删除品牌和供应商,它们彼此相关并且品牌与产品相关,我在进行最终删除之前删除了这些关系(至少我认为我是)并且我收到此错误,我不确定我错过了什么。最初在品牌模型中与产品没有关系,关系在产品模型中。我在没有运气的情况下将关系添加到品牌模型,结果仍然相同。


表结构


Schema::create('vendors', function (Blueprint $table)

        {

            $table->increments('id');

            $table->string('name');

            $table->string('image')->nullable();

            $table->timestamps();

        });


Schema::create('brands', function (Blueprint $table) {

            $table->increments('id');

            $table->string('name')->nullable();

            $table->integer('vendor_id')->unsigned();;

            $table->foreign('vendor_id')->references('id')->on('vendors');

            $table->timestamps();

        });


Schema::create('products', function (Blueprint $table) {

            $table->increments('id');

            $table->string('code');

            $table->string('sku')->nullable();

            $table->text('description_spanish');

            $table->text('description_english');

            $table->string('image')->nullable();

            $table->string('discount');

            $table->string('cif')->nullable();

            $table->string('color')->nullable();

            $table->string('color_ab')->nullable();

            $table->integer('brand_id')->unsigned();

            $table->timestamps();


            $table->foreign('brand_id')->references('id')->on('brands');

        });

模型和关系


class Vendor extends Model

{

    protected $hidden = ['created_at','updated_at'];


    public function  brands(){

        return $this->hasMany(Brand::class);

    }

}


class Brand extends Model

{

    public function vendor() {

        return $this->belongsTo(Vendor::class);

    }


    public function products() {

        return $this->hasMany(Product::class);

    }


}


class Product extends Products

{

    public function brand()

        {

            return $this->belongsTo(Brand::class);

        }

}

销毁控制器中的函数


HUH函数
浏览 194回答 3
3回答

叮当猫咪

如果要在删除记录时始终删除所有子关系,可以在模型的 boot 函数中的删除方法中进行。像这样的东西:供应商模型class Vendor extends Model{    public static function boot() {        parent::boot();        // when you are deleting a Vendor, also delete all related brands        static::deleting(function($vendor){             $vendor->brands->each(function($brand) {                $brand->delete();            });        });    }    protected $hidden = ['created_at','updated_at'];    public function  brands(){        return $this->hasMany(Brand::class);    }}品牌型号class Brand extends Model{    public static function boot() {        parent::boot();        // when you are deleting a Brand, also delete all related products        static::deleting(function($brand){             $brand->products->each(function($product) {                $product->delete();            });        });    }    public function vendor() {        return $this->belongsTo(Vendor::class);    }    public function products() {        return $this->hasMany(Product::class);    }}产品型号class Product extends Products{    public static function boot() {        parent::boot();        // when you are deleting a Product, also delete/detach all you need        static::deleting(function($product){             /*            $product->sizes()->detach();            $product->tags()->detach();            $product->fields()->detach();            $product->countries()->detach();            $product->exportationFactors->each(function($exportationFactor) {                $exportationFactor->delete();            });            */        });    }    public function brand()        {            return $this->belongsTo(Brand::class);        }}然后在您的控制器中删除与每个控制器对应的记录。供应商销毁功能public function destroy($id){    DB::beginTransaction();    Vendor::findOrFail($id)->delete();    DB::commit();}品牌破坏功能public function destroy($id){    DB::beginTransaction();    Brand::findOrFail($id)->delete();    DB::commit();}产品销毁功能public function destroy($id){    $product = Product::findOrFail($id);    DB::beginTransaction();    $this->removeProductImage($product);    $product->delete();    DB::commit();}

喵喵时光机

添加你拥有的onDelete('cascade')每一个$table->foreign('<Column>')。例子:$table->foreign('vendor_id')->references('id')->on('vendors')->onDelete('cascade');然后不需要先删除所有的孩子,只需删除父母。

www说

您遇到的问题在产品表中,有两种方法可以解决此问题:解决方案1:就像 Yovi 的回答状态一样,您可以简单地onDelete('cascade')在您的品牌和产品表中添加您的外键。品牌表:$table->foreign('vendor_id')->references('id')->on('vendors')->onDelete('cascade');产品表:$table->foreign('brand_id')->references('id')->on('brands')->onDelete('cascade');然后您的控制器销毁方法应如下所示:供应商销毁功能:public function destroy($id){&nbsp; &nbsp; $vendor = Vendor::findOrFail($id);&nbsp; &nbsp; $vendor->delete();}品牌销毁方法:public function destroy($id){&nbsp; &nbsp; $brand= Brand::findOrFail($id);&nbsp; &nbsp; $brand->delete();}解决方案2:如果你想手动删除你的行,你只是在你的销毁方法上设置了错误的顺序。您必须首先从产品 -> 品牌 -> 供应商开始删除最小的孩子。您的方法应如下所示:供应商销毁功能:public function destroy($id){&nbsp; &nbsp; DB::beginTransaction();&nbsp; &nbsp; $vendor = Vendor::findOrFail($id);&nbsp; &nbsp; foreach($vendor->brands() as $brand){&nbsp; &nbsp; &nbsp; &nbsp; $brand->products()->delete();&nbsp; &nbsp; }&nbsp; &nbsp; $vendor->brands()->delete();&nbsp; &nbsp; $vendor->delete();&nbsp; &nbsp; DB::commit();}品牌销毁功能:public function destroy($id){&nbsp; &nbsp; DB::beginTransaction();&nbsp; &nbsp; $brand= Brand::findOrFail($id);&nbsp; &nbsp; $brand->products()->delete();&nbsp; &nbsp; $brand->delete();&nbsp; &nbsp; DB::commit();}总的来说,我发现解决方案 1 更清洁。
随时随地看视频慕课网APP
我要回答