Login to bookmark this video
Buy Access to Course
13.

Agujero negro: Borrar entidades

|

Share this awesome video!

|

Keep on Learning!

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

Oh-oh, acabamos de enterarnos de que esta nave, el USS Leafy Cruiser, ha caído en un agujero negro. Por suerte, no había a bordo ningún personaje querido a largo plazo, pero esta nave está ahora espaguetizada. Como ya no existe en esta realidad, tenemos que eliminarla de nuestra base de datos.

app:ship:remove Comando

Vamos a crear un comando para gestionar esto. En tu terminal, ejecuta:

symfony console make:command

Para el nombre, utiliza app:ship:remove. Esto ha creado una nueva clase de comando.

Constructor de comandos

¡Ábrelo! src/Command/ShipRemoveCommand.php. El creador añadió algo de código repetitivo para nosotros. Actualiza la descripción a Delete a starship:

56 lines | src/Command/ShipRemoveCommand.php
// ... lines 1 - 13
#[AsCommand(
name: 'app:ship:remove',
description: 'Delete a starship',
)]
class ShipRemoveCommand extends Command
// ... lines 19 - 56

En el constructor, necesitamos inyectar dos cosas: private ShipRepository $shipRepo y private EntityManagerInterface $em:

56 lines | src/Command/ShipRemoveCommand.php
// ... lines 1 - 17
class ShipRemoveCommand extends Command
{
public function __construct(
private StarshipRepository $shipRepo,
private EntityManagerInterface $em,
) {
parent::__construct();
}
// ... lines 26 - 54
}

Cuando necesites encontrar o recuperar entidades, utiliza el repositorio. Cuando necesites gestionar entidades, como persistir, actualizar o eliminar, utiliza el gestor de entidades, o "EM" para abreviar.

Configuración del comando

En el método configure(), elimina addOption(). Para addArgument(), cambia el nombre a slug, establece InputArgument::REQUIRED, y actualiza la descripción a The slug of the starship:

56 lines | src/Command/ShipRemoveCommand.php
// ... lines 1 - 17
class ShipRemoveCommand extends Command
{
// ... lines 20 - 26
protected function configure(): void
{
$this
->addArgument('slug', InputArgument::REQUIRED, 'The slug of the starship')
;
}
// ... lines 33 - 54
}

Lógica de mando

Abajo en execute(), sustituye este $arg1 = por $slug = $input->getArgument('slug'):

56 lines | src/Command/ShipRemoveCommand.php
// ... lines 1 - 17
class ShipRemoveCommand extends Command
{
// ... lines 20 - 33
protected function execute(InputInterface $input, OutputInterface $output): int
{
// ... line 36
$slug = $input->getArgument('slug');
// ... lines 38 - 53
}
}

A continuación, tenemos que encontrar el barco por esta babosa. Cada EntityRepository ya tiene el método perfecto para ello. Escribe $ship = $this->shipRepo->findOneBy() pasando un array donde la clave es la propiedad a buscar y el valor es el valor a buscar: ['slug' => $slug]:

56 lines | src/Command/ShipRemoveCommand.php
// ... lines 1 - 17
class ShipRemoveCommand extends Command
{
// ... lines 20 - 33
protected function execute(InputInterface $input, OutputInterface $output): int
{
// ... lines 36 - 37
$ship = $this->shipRepo->findOneBy(['slug' => $slug]);
// ... lines 39 - 53
}
}

Al utilizar estos métodos de búsqueda preconfigurados, Doctrine escapa automáticamente los valores, por lo que no tienes que preocuparte por los ataques de inyección SQL.

Ajusta esta sentencia if a if (!$ship). findOneBy() devuelve null si no se ha encontrado una entidad. Dentro, escribe $io->error('Starship not found.') y devuelve Command::FAILURE:

56 lines | src/Command/ShipRemoveCommand.php
// ... lines 1 - 17
class ShipRemoveCommand extends Command
{
// ... lines 20 - 33
protected function execute(InputInterface $input, OutputInterface $output): int
{
// ... lines 36 - 39
if (!$ship) {
$io->error('Starship not found.');
return Command::FAILURE;
}
// ... lines 45 - 53
}
}

Escribe un comentario para informar al usuario de que estamos a punto de eliminar la nave estelar.$io->comment(sprintf('Removing starship %s', $ship->getName())):

56 lines | src/Command/ShipRemoveCommand.php
// ... lines 1 - 17
class ShipRemoveCommand extends Command
{
// ... lines 20 - 33
protected function execute(InputInterface $input, OutputInterface $output): int
{
// ... lines 36 - 45
$io->comment(sprintf('Removing starship: %s', $ship->getName()));
// ... lines 47 - 53
}
}

Elimina esta repetición adicional y escribe $this->em->remove($ship). Al igual que con persist(),remove() en realidad no elimina la entidad directamente, sino que la añade a una cola de entidades que se eliminarán cuando llamemos a $this->em->flush():

56 lines | src/Command/ShipRemoveCommand.php
// ... lines 1 - 17
class ShipRemoveCommand extends Command
{
// ... lines 20 - 33
protected function execute(InputInterface $input, OutputInterface $output): int
{
// ... lines 36 - 47
$this->em->remove($ship);
$this->em->flush();
// ... lines 50 - 53
}
}

Añade un mensaje de éxito con $io->success('Starship removed.'):

56 lines | src/Command/ShipRemoveCommand.php
// ... lines 1 - 17
class ShipRemoveCommand extends Command
{
// ... lines 20 - 33
protected function execute(InputInterface $input, OutputInterface $output): int
{
// ... lines 36 - 50
$io->success('Starship removed.');
return Command::SUCCESS;
}
}

¡Comando realizado!

Vuelve a nuestra aplicación y actualiza la página para asegurarte de que el barco sigue ahí. Ahora, copia el slug de la URL.

Ejecutar el comando

De nuevo en tu terminal, Ejecuta:

symfony console app:ship:remove

Pega el slug copiado y ejecuta. ¡Éxito! Nave estelar eliminada. Ejecuta de nuevo el mismo comando.

symfony console app:ship:remove leafy-cruiser-ncc-0001

"Nave estelar no encontrada" ¡Perfecto! De nuevo en la aplicación, actualiza la página. 404. ¡La nave ha desaparecido de la base de datos!

¡Muy bien! Hemos visto cómo persistir y eliminar entidades. A continuación, veremos cómo actualizar la entidad nave estelar.