Why can't I delete this from my tables that have relationships?

杀马特。学长 韩版系。学妹 提交于 2019-12-13 03:40:41

问题


Why can't I delete these items from my database, they only have one relationship each, and I'm detaching and deleting each respectively. I have 3 tables Vendor, Brand and Product. The error mentions the Products table but there are no relationships in the Vendor table to the Products table, the relationship is with the Brand table and it's a one to one relationship.

Table structure

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');
        });

Vendor Model and relationship

class Vendor extends Model
{
    protected $hidden = ['created_at','updated_at'];

    public function  brands(){
        return $this->hasMany(Brand::class);
    }
}

Brand Model and relationship

class Brand extends Model
{
    public function vendor() {
        return $this->belongsTo(Vendor::class);
    }
}

Product relationship with Brand

public function brand()
    {
        return $this->belongsTo(Brand::class);
    }

Vendor destroy function

public function destroy($id)
    {
        DB::beginTransaction();
        $vendor = Vendor::findOrFail($id);
        $vendor->brands()->delete();
        $vendor->delete();
        DB::commit();

    }

Brand destroy function

public function destroy($id)
    {
        DB::beginTransaction();
        $vendor = Brand::findOrFail($id);
        $vendor->vendors()->delete();
        $vendor->delete();
        DB::commit();
    }

Product destroy funcion

public function destroy($id)
    {
        $product = Product::findOrFail($id);
        DB::beginTransaction();
        $product->sizes()->detach();
        $product->tags()->detach();
        $product->fields()->detach();
        $product->countries()->detach();
        $this->removeProductImage($product);
        $product->exportationFactors()->delete();
        $product->delete();
        DB::commit();
    }

when I try to delete a Vendor I recieve this error

SQLSTATE[23000]: Integrity constraint violation: 
1451 Cannot delete or update a parent row: 
a foreign key constraint fails (`sondel`.`products`, 
CONSTRAINT `products_brand_id_foreign`FOREIGN KEY (`brand_id`) 
REFERENCES `brands` (`id`)) (SQL: delete from `brands` where 
`brands`.`vendor_id` = 2 and `brands`.`vendor_id` is not null)

and when I try to delete a Brand I have basically the same error

SQLSTATE[23000]: Integrity constraint violation: 
1451 Cannot delete or update a parent row: 
a foreign key constraint fails (`sondel`.`brands`, CONSTRAINT
 `brands_vendor_id_foreign` FOREIGN KEY (`vendor_id`) 
REFERENCES `vendors` (`id`)) (SQL: delete from `vendors` 
where `vendors`.`id` = 2)

I'm not sure what I'm doing wrong.


回答1:


Error on Vendor Delete is Because You are deleting Vendor's all Brands which are again related to Products So, without deleting their related products you can't delete them. So, you have to delete products at first. Create a relation of Products on Brand Model

public function  products(){
    return $this->hasMany(Products::class);
}

Then on Vendor's destroy get its all brands loop through and delete all products.

DB::beginTransaction();
$vendor = Vendor::findOrFail($id);
$vendor->brands->each(function ($brand) {
    $brand->products->each(function ($product) {
         $product->sizes()->detach();
         $product->tags()->detach();
         $product->fields()->detach();
         $product->countries()->detach();
         $this->removeProductImage($product);
         $product->exportationFactors()->delete();
         $product->delete();
    });
});
$vendor->brands()->delete();
$vendor->delete();
DB::commit();

Same On Brand's delete get all its products and delete its products first.

DB::beginTransaction();
$brand = Brand::findOrFail($id);
$brand->products->each(function ($product) {
     $product->sizes()->detach();
     $product->tags()->detach();
     $product->fields()->detach();
     $product->countries()->detach();
     $this->removeProductImage($product);
     $product->exportationFactors()->delete();
     $product->delete();
});
$brand->delete();
DB::commit();

I would like to suggest you to use Eloquent's deleting event on all three models then you will not need to care about nested model's foreign key and you will get rid of code repitation. see: https://laravel.com/docs/6.0/eloquent#events



来源:https://stackoverflow.com/questions/57895468/why-cant-i-delete-this-from-my-tables-that-have-relationships

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!