Guía Completa Cómo Implementar Soft Delete en Symfony 7.x Paso a Paso (imagen destacada)

Tiro monedas al aire, pero hasta ahora nunca las pude agarrar.

Visitas: 21

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
Crear entidad User en Symfony 7.x
Crear entidad User en Symfony 7.x

– 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

uerto 5432 en docker compose
Puerto 5432 en docker compose

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
Listar contenedores en docker
Listar contenedores en docker

Ahora creamos la migración para nuestra entidad User:

php bin/console make:migration

Verificamos si está correcto el archivo que recién creamos.

Archivo migración en Symfony
Archivo migración en Symfony

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

Tabla user
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

Post endpoint user
Post endpoint user

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;

Soft Delete en la entidad User en Symfony
Soft Delete en la entidad User en Symfony

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.

Campo deleted_at en la tabla user
Campo deleted_at en la tabla user

Ahora creamos un nuevo registro usando nuestro cliente REST

Nuevo usuario usando el endpoint por el método POST
Nuevo usuario usando el endpoint por el método POST

Pueden observar que hemos creado un usuario.

Ahora vamos a eliminar el usuario usando el método Delete

Borramos el usuario mediante el método DELETE
Borramos el usuario mediante 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

Registros de la tabla user
Registros de la tabla user

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.

Obtener todos los usuarios mediante el endpoint users
Obtener todos los usuarios mediante el endpoint users

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


Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *