2
votes

First project on laravel : When I am going to delete row it throws an Error : SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails. My controller function

 public function delete(Request $request) {
    try {
        Venue::findOrFail($request->id)->delete();
    } catch (\Exception $ex) {
        return response()->json([
                'error' => $ex->getCode(),
                'message' => $ex->getMessage()
            ]);
    }

    return response()->json([
            'message' => trans('admin.venue.delete_success')
        ]);
}

Model :

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

    self::deleting(function (Venue $venue) {
        $venue->occasions()->delete();
        $venue->contact()->delete();
        $venue->gallery()->delete(); // here i am gtng error
        $venue->venueParameter()->delete();
    });
}

Error in detail :

SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (red_carpet.media, CONSTRAINT media_gallery_id_foreign FOREIGN KEY (gallery_id) REFERENCES galleries (id)) (SQL: delete from galleries where galleries.source_id = 2 and galleries.source_id is not null and galleries.source_type = App\Venue)

Schema of table :

Schema::create('venues', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('client_id');
        $table->string('name');
        $table->string('logo');
        $table->unsignedInteger('venue_type_id');
        $table->boolean('is_premium');
        $table->boolean('is_verified');
        $table->string('tripadvisor_url')->nullable();
        $table->enum('status',['Active','Inactive']);
        $table->timestamps();

        $table->foreign('client_id')->references('id')->on('clients');
        $table->foreign('venue_type_id')->references('id')->on('venue_types');
    });

  Schema::create('galleries', function (Blueprint $table) {
        $table->increments('id');
        $table->string('source_type');
        $table->unsignedInteger('source_id');
        $table->string('title');
        $table->unsignedInteger('sort_order');
        $table->enum('status',['Active','Inactive']);
        $table->timestamps();
    });
    Schema::create('media', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('gallery_id');
        $table->enum('type',['Image','Video']);
        $table->string('caption');
        $table->string('path')->nullable();
        $table->string('thumbnail')->nullable();
        $table->longText('video_code')->nullable();
        $table->boolean('is_banner_image')->default(false);
        $table->boolean('is_thumb_image')->default(false);
        $table->unsignedInteger('sort_order');
        $table->enum('status',['Active','Inactive']);
        $table->timestamps();

        $table->foreign('gallery_id')->references('id')->on('galleries');
    });
5
you cannot delete parent row as it violates foreign key constraint. you should use ->onDelete('cascade'); where you have defined your foreign keyprogrammingArrow
can't delete gallery because media has records pointing to those keyslagbox
Where i can add cascade as i do not know about more.Javed
Can you show shema of all tables involved in the error?programmingArrow
you want to see table structure ?Javed

5 Answers

4
votes

If you are deleting items from one table that are linked with the other table, then it gives you this error.

If you are using a pivot table, then use onDelete('cascade') like,

$table->foreign('foreign_key')->references('primary_key')->on('table_name')->onDelete('cascade');

Ref:

2
votes

You can add

  onDelete('cascade')
0
votes

In your table, For example:

$table->foreign('user_id') ->references('id')->on('users') ->onDelete('cascade');
0
votes

Go to your gallery migration file inside database/migrations/examplegallerytable.php and update the relationship definition to these:

$table->foreign('media_id')->references('id')->on('medias')->onDelete('cascade');

then run these command:

php artisan migrate:reset

and

php artisan migrate

that's all

0
votes

As others have suggested, you can use onDelete method to prevent the error. But I dont recommend to actually delete your records in the database.

You can use SoftDeletes to delete records by adding a deleted_at timestamp field to your table schema. Then all your queries will only fetch rows where deleted_at IS null

To enable this in your models, make sure that your tables has $table->softDeletes(). This will add the necessary deleted_at field to your tables.

Next, add the Illuminate\Database\Eloquent\SoftDeletes trait to your models like this.

use Illuminate\Database\Eloquent\Model; 
use Illuminate\Database\Eloquent\SoftDeletes; 

class Foo extends Model { 
    use SoftDeletes; 
}

Aaannd, that's it! Every time you perform a query with Foo, all non-null deleted_at value will be ignored.

$foos = Foo::all();

And whenever you perform delete(), it will simply update deleted_at to the current timestamp.