简体   繁体   中英

Laravel Cannot delete or update a parent row: a foreign key constraint fails

For some reason a user cannot delete a post if it has been liked, it was working before but when I linked posts with likes I have been getting this error, I can't even delete it in Sequel Pro, unless I delete the likes associated with the post first.

Error

SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails ( eliapi8 . likes , CONSTRAINT likes_post_id_foreign FOREIGN KEY ( post_id ) REFERENCES posts ( id )) (SQL: delete from posts where id = 149)

Maybe it's my schema?

Posts Schema

Schema::create('posts', function (Blueprint $table) {
    $table->increments('id');
    $table->string('title');
    $table->text('body');
    $table->integer('user_id')->unsigned();
    $table->foreign('user_id')->references('id')->on('users');
    $table->timestamps();
});

Likes Schema

Schema::create('likes', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('post_id')->unsigned();
    $table->integer('user_id')->unsigned();
    $table->foreign('post_id')->references('id')->on('posts');
    $table->foreign('user_id')->references('id')->on('users');
    $table->softDeletes();
    $table->timestamps();
});

I can like and unlike a post, but a user cannot delete a post that has been liked.

PostController.php

public function destroy(Post $post){
    
    $this->authorize('delete', $post);
    $postl =  Post::with('likes')->whereId($post)->delete();

    if ($post->delete()) {
        if($postl){
             return response()->json(['message' => 'deleted']);
        }  
    };

    return response()->json(['error' => 'something went wrong'], 400);
}

Yes, it's your schema. The constraint on likes.post_id will prevent you from deleting records from the posts table.

One solution could be using onDelete('cascade') in the likes migration file:

Schema::create('likes', function (Blueprint $table) {
    $table->integer('post_id')->unsigned();
    $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
});

This way, when a post is deleted, all related likes will be deleted too.

Or, if you have a relationship from the Post model to the Like model, you can $post->likes()->delete() before deleting the post itself.

I've tested with onDelete('cascade') but in my case it didn't work. The resource I tried to delete had a model with an hasMany()

/**
 * Get the departments of the organization
 *
 * @return void
 */
public function org_departments()
{
    return $this->hasMany(Department::class);
}

So, in the destroy() for the controller OrganizationUserController , instead of having

$organization->delete();

I ensured to delete the departments for that organization first and only then the $organization ,

$organization->org_departments()->delete();

$organization->delete();

Then it was deleted just fine.

If you are in production mode just php artisan migrate:fresh. It will drop all tables
Note:Record would be deleted from tables
Why you Face this problem??
Actually you cant delete parent table having data in child table . First you have to delete the child table data only than can you delete the parent table

you have two option to handle this issue.
1)->onDelete('cascade') with your forigner key in migrations
2) if you are in controller first delete $organization->org_departments()->delete(); so all your child would be deleted first than you can delete the parent child $organization->delete();

on delete更改为cascade ,而不是restrict

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM