Cuando borro una fila usando esta sintaxis:
$user->delete();
¿Hay alguna forma de adjuntar una especie de devolución de llamada, de modo que, por ejemplo, haga esto automáticamente:
$this->photo()->delete();
Preferiblemente dentro de la clase de modelo.
first()
a la consulta para poder acceder al evento modelo, por ejemplo,User::where('id', '=', $id)->first()->delete();
Fuenteforeach($user->photos as $photo)
, luego$photo->delete()
para asegurarme de que a cada niño se le quitaran los niños en todos los niveles, en lugar de solo uno, ya que estaba sucediendo por alguna razón.Photos
tienetags
y hace lo mismo en elPhotos
modelo (es decir, en eldeleting
método$photo->tags()->delete();
:) nunca se activa. Pero si hago unfor
bucle y hago algo asífor($user->photos as $photo) { $photo->delete(); }
, ¡tags
también se borrará! solo para tu informaciónDe hecho, puede configurar esto en sus migraciones:
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
Fuente: http://laravel.com/docs/5.1/migrations#foreign-key-constraints
fuente
Puede eliminar todas las fotos relacionadas antes de eliminar realmente al usuario.
Espero eso ayude.
fuente
$this->photos()->delete()
. Elphotos()
devuelve el objeto generador de consultas.Relación en modelo de usuario:
Eliminar registro y relacionado:
fuente
Hay 3 enfoques para resolver esto:
1. Uso de eventos elocuentes en el arranque del modelo (ref: https://laravel.com/docs/5.7/eloquent#events )
2. Uso de observadores de eventos elocuentes (ref: https://laravel.com/docs/5.7/eloquent#observers )
En su AppServiceProvider, registre el observador así:
A continuación, agregue una clase Observer así:
3. Uso de restricciones de clave externa (ref: https://laravel.com/docs/5.7/migrations#foreign-key-constraints )
fuente
A partir de Laravel 5.2, la documentación establece que este tipo de controladores de eventos deben registrarse en AppServiceProvider:
Incluso supongo moverlos a clases separadas en lugar de cierres para una mejor estructura de aplicación.
fuente
Eloquent::observe()
método también está disponible en 5.2 y se puede usar desde AppServiceProvider.photos()
, también deberá tener cuidado: este proceso no eliminará a los nietos porque no está cargando modelos. Tendrá que recorrerphotos
(tenga en cuenta que nophotos()
) y activar eldelete()
método en ellos como modelos para activar los eventos relacionados con la eliminación.Es mejor si anula el
delete
método para esto. De esa manera, puede incorporar transacciones de DB dentro deldelete
método mismo. Si utiliza la forma de evento, deberá cubrir su llamada dedelete
método con una transacción de base de datos cada vez que la llame.En tu
User
modelo.fuente
En mi caso fue bastante simple porque las tablas de mi base de datos son InnoDB con claves foráneas con Cascade en Delete.
Entonces, en este caso, si su tabla de fotos contiene una referencia de clave externa para el usuario, lo único que tiene que hacer es eliminar el hotel y la base de datos realizará la limpieza, la base de datos eliminará todos los registros de fotos de los datos base.
fuente
Recorrería la colección separando todo antes de eliminar el objeto en sí.
Aquí hay un ejemplo:
Sé que no es automático, pero es muy simple.
Otro enfoque simple sería proporcionar al modelo un método. Me gusta esto:
Entonces simplemente puede llamar a esto donde lo necesite:
fuente
O puede hacer esto si lo desea, solo otra opción:
Tenga en cuenta que si no está utilizando la conexión de laravel db predeterminada, debe hacer lo siguiente:
fuente
Para elaborar la respuesta seleccionada, si sus relaciones también tienen relaciones secundarias que deben eliminarse, primero debe recuperar todos los registros de relaciones secundarias, luego llamar al
delete()
método para que sus eventos de eliminación también se activen correctamente.Puede hacerlo fácilmente con mensajes de orden superior .
También puede mejorar el rendimiento consultando solo la columna ID de relaciones:
fuente
sí, pero como @supersan declaró arriba en un comentario, si elimina () en un QueryBuilder, el evento del modelo no se activará, porque no estamos cargando el modelo en sí, y luego llamando a delete () en ese modelo.
Los eventos se activan solo si utilizamos la función de eliminación en una instancia de modelo.
Entonces, este beeing dijo:
para eliminar las etiquetas de publicación al eliminar el usuario, tendríamos que repetir
$user->posts
y llamar$post->delete()
foreach($user->posts as $post) { $post->delete(); }
-> esto activará el evento de eliminación en la publicaciónVS
$user->posts()->delete()
-> esto no activará el evento de eliminación en la publicación porque en realidad no cargamos el modelo de publicación (solo ejecutamos un SQL como:DELETE * from posts where user_id = $user->id
y, por lo tanto, el modelo de publicación ni siquiera se carga)fuente
Puede usar este método como alternativa.
Lo que sucederá es que tomamos todas las tablas asociadas con la tabla de usuarios y eliminamos los datos relacionados mediante el bucle
fuente