Sistema de trazabilidad en Laravel con relaciones polimórficas y traits

En muchos proyectos es fundamental contar con un historial de cambios que nos permita saber quién modificó qué dato, en qué momento y cuál fue la diferencia antes y después. Este historial de cambios suele conocerse como un sistema de trazabilidad o revisiones (revision history). En este artículo aprenderás a desarrollar, desde cero y sin dependencias adicionales, un sistema que registre la creación, actualización y eliminación de registros en tu aplicación Laravel.

1. ¿En qué consiste nuestro sistema de revisiones?

La idea principal es tener un modelo Revision que guarde la información de:

  • El usuario que realizó el cambio (usamos un morphs('owner'), para mayor flexibilidad).

  • El modelo que fue modificado (usamos un morphs('revisionable')).

  • La columna modificada, junto con su valor anterior y su valor nuevo.

  • Un campo de comentarios para saber si fue creado, actualizado o eliminado.

Lo lograremos con:

  1. Un modelo y migración Revision que almacenará los cambios.

  2. Un trait Revisionable que se inyecta en cualquier modelo que deseemos auditar. Este trait intercepta los eventos created, updated y deleted, y registra en la base de datos la información necesaria.

  3. Relaciones polimórficas para vincular el modelo Revision con cualquier otro modelo (p. ej., Ticket, Article, etc.).

2. Creando el modelo y migración Revision

Lo primero será generar el modelo Revision y su migración. Para ello, ejecuta:

Esto creará el archivo de migración y el modelo. A continuación, ajusta el contenido de la migración (database/migrations/..._create_revisions_table.php) de la siguiente manera:

Ya con la migración lista, podemos definir el modelo Revision:

Con esto, tenemos todo lo necesario para almacenar los cambios en la tabla revisions.

3. El trait Revisionable

Ahora crearemos un trait que se incluirá en cualquier modelo que queramos auditar. Este trait hará uso de los eventos de Eloquent (created, updated, deleted) para capturar los cambios y guardarlos en la tabla revisions.

Crea el archivo app/Traits/Revisionable.php con el siguiente contenido:

¿Cómo funciona?

  • El trait define una relación polimórfica revisions() con el modelo Revision.

  • Dentro de bootRevisionable(), enganchamos tres eventos importantes:

    • created: Para cada columna auditable, se registra una fila que indica que el valor antiguo era null y el nuevo es el que se ha creado.

    • updated: Solo registra una nueva fila cuando detecta que una columna marcada como revisionable ha cambiado.

    • deleted: Marca el valor viejo como el que existía y el nuevo como null, indicando que se ha eliminado.

Es fundamental que cada modelo defina una propiedad protected array $revisionableColumns donde listemos las columnas que queremos auditar.

4. Ejemplo de uso: Modelo Ticket

Imagina que tenemos un modelo Ticket con la siguiente migración:

En la migración (resumen):

Y el modelo Ticket quedaría así:

Cuando se cree, actualice o elimine un ticket, se registrarán las revisiones correspondientes en la tabla revisions.

5. Otro ejemplo: Modelo Article

De manera análoga, podemos hacer lo mismo con un modelo Article:

  • Migración:

  • Modelo:

En este caso, se registrarán los cambios en el title y content cada vez que se modifique o elimine un artículo.

6. Cómo consultar las revisiones

Para acceder al historial de cambios de un modelo, basta con utilizar la relación revisions():

Lo mismo aplica para un Article u otro modelo que use el trait Revisionable.

7. Conclusiones y recomendaciones

  • Flexibilidad: El uso de relaciones polimórficas permite auditar múltiples modelos con una sola tabla de revisiones.

  • Escalabilidad: El trait está basado en eventos de Eloquent, por lo que no hay dependencias de paquetes externos.

  • Control de columnas: Al definir $revisionableColumns, controlamos exactamente qué campos se registran en las revisiones, evitando sobrecargar la tabla con datos innecesarios.

  • Consideraciones de rendimiento: Cada inserción o actualización genera nuevos registros en la tabla revisions. Para aplicaciones con mucha actividad, es recomendable monitorizar el tamaño de esta tabla y definir estrategias de limpieza.

  • Seguridad y permisos: El trait actual asume que hay un usuario autenticado con auth()->user(). En entornos donde esta suposición no sea válida, conviene ajustar la lógica (por ejemplo, para manejar procesos automatizados).

Con esto, ya tienes un sistema de trazabilidad completo que te permitirá ver qué se modificó, quién lo modificó y cuáles eran los valores antes y después de cada cambio. ¡Espero que esta guía te ayude a mantener el control y la transparencia en tu aplicación Laravel!

Cursosdesarrolloweb es una plataforma educativa con cursos y tutoriales en texto y vídeo.

Términos y condiciones Política de privacidad Términos y condiciones para afiliados Formulario de contacto

Copyright 2025 © Todos los derechos reservados.

Contacto