Visitas: 46
En muchos proyectos web, es común que en lugar de eliminar permanentemente un registro de la base de datos, se prefiera hacer un Soft Delete. Este enfoque permite marcar los datos como eliminados sin realmente borrarlos.
En este artículo te enseñaremos cómo implementar Soft Delete en un proyecto con Symfony 7.x desde cero. Veremos paso a paso cómo configurar tu entidad, añadir la lógica necesaria y asegurarnos de que el proceso sea eficiente y funcional.
¿Qué es el Soft Delete?
El Soft Delete es una técnica que consiste en agregar un campo a la base de datos, como por ejemplo deleted_at. En el campo deleted_at se almacena la fecha y hora en la que un registro fue marcado como “eliminado”. Si el campo tiene un valor NULL, significa que el registro sigue activo. De lo contrario, está “eliminado” sin ser removido físicamente (borrado físico).
Ahora manos a la obra, creamos un proyecto en Symfony, entramos a la terminal y tecleamos lo siguiente:
symfony new test-entity-soft-delete cd test-entity-soft-delete
Instalamos el paquete ORM para poder conectarnos a una base de datos relacional como PostgreSQL:
composer require symfony/orm-pack
Instalamos un paquete para usar en nuestros desarrollos (por ejemplo, para crear una entidad mediante la consola)
composer require --dev symfony/maker-bundle
Ahora instalamos para tener una API REST y poder crear registros de nuestra entidad, eliminar y listar.
composer require api
Ahora instalamos los paquetes relacionados con las extensiones doctrine.
composer require gedmo/doctrine-extensions composer require stof/doctrine-extensions-bundle
Ahora configuramos la parte de Soft Delete. Entramos en el archivo config/packages/doctrine.yaml
doctrine: orm: auto_mapping: true filters: softdeleteable: class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter enabled: true
Ahora configuramos en el archivo config/packages/stof_doctrine_extensions.yaml
stof_doctrine_extensions: default_locale: en_US orm: default: timestampable: true softdeleteable: true
Ahora creamos nuestra entidad llamada User
php bin/console make:entity
– La entidad User expone CRUD a API REST
– Las propiedades que creamos es name (no obligatorio) y email (obligatorio)
Ahora debemos crear la tabla en la base de datos. En nuestro ejemplo vamos a usar docker compose
Editamos el archivo compose.override.yaml
Agregamos el puerto 5432
Ahora tecleamos lo siguiente en la terminal:
docker compose up -d
Para ver si nuestro contenedor de base de datos está prendido usando el puerto 5432
docker ps
Ahora creamos la migración para nuestra entidad User:
php bin/console make:migration
Verificamos si está correcto el archivo que recién creamos.
Una vez que hayamos verificado, y se encuentra todo correcto, ejecutamos lo siguiente:
php bin/console doctrine:migrations:migrate
Entramos a nuestro gestor de base de datos favorito y verificamos que se encuentre la tabla user
En mi caso, estoy usando un plugin en Visual Studio Code para visualizar tablas, registros, etc
Ahora levantamos un servidor de desarrollo para tener nuestra API disponible. En nuestro caso disponemos de un api con un endpoint user.
symfony server:start --port=8080
Usamos un cliente para hacer un POST. Pueden usar Postman o una extensión de REST en Visual Studio Code. En mi caso utilizo Thunder Client
Pueden observar en la imagen de arriba que usamos el endpoint http://127.0.0.1:8080/api/users por el método POST para crear un nuevo usuario.
Si eliminamos el usuario mediante el método DELETE, el borrado va a ser físico, ya no podremos recuperar ese registro.
Para no perder el registro después de una eliminación usando el método DELETE vamos a agregar en nuestra entidad User, el Soft Delete o borrado lógico.
Editamos nuestro entity User:
namespace App\Entity; use ApiPlatform\Metadata\ApiResource; use App\Repository\UserRepository; use Doctrine\ORM\Mapping as ORM; use Gedmo\Mapping\Annotation as Gedmo; use Gedmo\SoftDeleteable\Traits\SoftDeleteableEntity; #[ORM\Entity(repositoryClass: UserRepository::class)] #[ORM\Table(name: '`user`')] #[Gedmo\SoftDeleteable(fieldName: 'deletedAt', timeAware: false, hardDelete: false)] #[ApiResource] class User { /** * Hook SoftDeleteable behavior * updates deletedAt field */ use SoftDeleteableEntity; #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null;
Lo importante que se debe de agregar en una entidad para que el borrado sea soft delete son lo siguiente:<br ?–>
– Importar estos dos Gedmo\Mapping\Annotation as Gedmo y Gedmo\SoftDeleteable\Traits\SoftDeleteableEntity
– Agregar esta línea –> #[Gedmo\SoftDeleteable(fieldName: ‘deletedAt’, timeAware: false, hardDelete: false)]
– Agregar este trait dentro de la entidad –> use SoftDeleteableEntity;
Una vez que agregaste el Soft Delete en la entidad debemos de crear la migración y luego insertar en la base de datos
php bin/console make:migration php bin/console doctrine:migrations:migrate
Si te fijas ahora en la tabla, se creó un nuevo campo llamado deleted_at, que sirve para el Soft Delete.
Ahora creamos un nuevo registro usando nuestro cliente REST
Pueden observar que hemos creado un usuario.
Ahora vamos a eliminar el usuario usando el método Delete
Ahora verificamos nuestra tabla de la base de datos, si existe el usuario o que paso después del método delete
Como pueden observar el usuario que recién hemos eliminado por el método delete, en el campo deleted_at tiene una fecha. Eso quiere decir que en esa fecha se eliminó ese registro.
Luego si listamos usando el endpoint http://127.0.0.1:8080/api/users vamos a observar que se listan solamente los usuarios que tienen NULL en el campo deteled_at, eso quiere decir que los usuarios que fueron eliminados no se muestran.
Si por alguna razón se quiere volver a recuperar el usuario borrado, simplemente deben establecer el valor del campo deleted_at a NULL para el usuario que se desea recuperar.
Así de sencillo se puede restaurar el registro marcado como eliminado sin perder la información del mismo.
Imagen destacada: creada con DALL·E
Wiki: SoftDeleteable en Symfony
Código fuente: Symfony Entity Soft Delete