为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

PHP
HUH函数 2022-01-08 17:35:04
我正在尝试从我的数据库中删除品牌和供应商,它们彼此相关并且品牌与产品相关,我在进行最终删除之前删除了这些关系(至少我认为我是)并且我收到此错误,我不确定我错过了什么。最初在品牌模型中与产品没有关系,关系在产品模型中。我在没有运气的情况下将关系添加到品牌模型,结果仍然相同。表结构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);        }}销毁控制器中的函数
查看完整描述

3 回答

?
叮当猫咪

TA贡献1776条经验 获得超12个赞

如果要在删除记录时始终删除所有子关系,可以在模型的 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();

}


查看完整回答
反对 回复 2022-01-08
?
喵喵时光机

TA贡献1846条经验 获得超7个赞

添加你拥有的onDelete('cascade')每一个$table->foreign('<Column>')

例子:

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

然后不需要先删除所有的孩子,只需删除父母。


查看完整回答
反对 回复 2022-01-08
?
www说

TA贡献1775条经验 获得超8个赞

您遇到的问题在产品表中,有两种方法可以解决此问题:


解决方案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)

{

    $vendor = Vendor::findOrFail($id);

    $vendor->delete();


}

品牌销毁方法:


public function destroy($id)

{

    $brand= Brand::findOrFail($id);

    $brand->delete();

}

解决方案2:


如果你想手动删除你的行,你只是在你的销毁方法上设置了错误的顺序。您必须首先从产品 -> 品牌 -> 供应商开始删除最小的孩子。您的方法应如下所示:


供应商销毁功能:


public function destroy($id)

{

    DB::beginTransaction();

    $vendor = Vendor::findOrFail($id);


    foreach($vendor->brands() as $brand){

        $brand->products()->delete();

    }


    $vendor->brands()->delete();

    $vendor->delete();

    DB::commit();

}

品牌销毁功能:


public function destroy($id)

{

    DB::beginTransaction();

    $brand= Brand::findOrFail($id);

    $brand->products()->delete();

    $brand->delete();

    DB::commit();

}

总的来说,我发现解决方案 1 更清洁。


查看完整回答
反对 回复 2022-01-08
  • 3 回答
  • 0 关注
  • 193 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号