Laravel no puede eliminar o actualizar una fila principal: falla una restricción de clave externa

4 minutos de lectura

avatar de usuario
BARNOWL

Por alguna razón, un usuario no puede eliminar una publicación si le ha gustado, funcionaba antes, pero cuando vinculé publicaciones con Me gusta recibí este error, ni siquiera puedo eliminarlo en Sequel Pro, a menos que elimine los Me gusta asociados. primero con la publicación.

Error

ESTADO SQL[23000]: Violación de restricción de integridad: 1451 No se puede eliminar o actualizar una fila principal: falla una restricción de clave externa (eliapi8.likesRESTRICCIÓN likes_post_id_foreign CLAVE EXTERNA (post_id) REFERENCIAS posts (id)) (SQL: eliminar de posts dónde
id = 149)

¿Quizás es mi esquema?

Esquema de publicaciones

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

Esquema de Me gusta

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

Puedo indicar que me gusta y que me gusta una publicación, pero un usuario no puede eliminar una publicación a la que le ha gustado.

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

avatar de usuario
Camilo

Sí, es tu esquema. La restricción en likes.post_id le impedirá eliminar registros de la posts mesa.

Una solución podría ser usar onDelete('cascade') en el likes archivo de migración:

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

De esta manera, cuando se elimine una publicación, todos los Me gusta relacionados también se eliminarán.

O bien, si tiene una relación entre el modelo Publicar y el modelo Me gusta, puede $post->likes()->delete() antes de eliminar la publicación en sí.

  • funcionó, así que puedo usar onDelete si una publicación tiene Me gusta.

    – BARNOWL

    29 de noviembre de 2017 a las 2:50

  • Actualicé la respuesta sobre por qué no era posible eliminar registros del posts mesa.

    – Camilo

    29 de noviembre de 2017 a las 3:03

  • También uso ondelete con mi esquema y no se puede eliminar y me da el mismo error que obtuviste cuando uso $user->activities()->delete(); luego elimine al usuario y todos sus datos, pero cuando simplemente uso $user->delete(); me muestra el error por favor ayuda.

    – Moaíz

    28 de mayo de 2019 a las 11:16

  • @Moaiz Haga una nueva pregunta si es necesario.

    – Camilo

    31 de mayo de 2019 a las 1:17

  • ¿Cómo puede “agregar” -> onDelete (‘cascada’) a un modelo existente?

    – Hondaman900

    19 de febrero de 2020 a las 3:41

avatar de usuario
Tiago Martín Peres

he probado con onDelete('cascade') pero en mi caso no funcionó. El recurso que traté de eliminar tenía un modelo con un hasMany()

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

Entonces, en el destroy() para el controlador OrganizationUserControllerEn vez de tener

$organization->delete();

Me aseguré de eliminar los departamentos de esa organización primero y solo luego el $organization,

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

$organization->delete();

Luego se borró muy bien.

  • Esto funcionó para mí también. Gracias

    – AnkitS

    11 de febrero a las 4:20

  • Asante Sana, esto acaba de salvarme el tiempo

    – Makú

    21 de febrero a las 13:25

Si está en modo de producción, simplemente php artesanal migrar: fresco. Eliminará todas las tablas.

Nota: el registro se eliminaría de las tablas

¿Por qué te enfrentas a este problema?

En realidad, no puede eliminar la tabla principal que tiene datos en la tabla secundaria. Primero debe eliminar los datos de la tabla secundaria solo para poder eliminar la tabla principal

usted tiene dos opciones para manejar este problema.

1)->onDelete(‘cascade’) con tu clave extranjera en migraciones

2) si está en el controlador, primero elimine $organization->org_departments()->delete(); por lo tanto, todos sus hijos se eliminarán primero que usted puede eliminar el padre hijo $organization->delete();

Cambio on delete a cascadeen vez de restrict.

Laravel no puede eliminar o actualizar una fila principal: falla una restricción de clave externa

¿Ha sido útil esta solución?