Login to bookmark this video
Buy Access to Course
14.

Actualizaciones de barcos: Actualización de una entidad

|

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

Nuestro negocio de reparación de naves va viento en popa Ahora tenemos algunos clientes que repiten y quieren algunas mejoras posteriores. Necesitamos una forma de registrar una nave estelar existente cuyo estado sea completada.

Encontrar una nave completada

En la lista de nuestra página de inicio sólo aparecen naves estelares incompletas, así que tenemos que encontrar una completada. Ejecuta en tu terminal:

symfony console doctrine:query:sql 'SELECT slug, status FROM starship'

lunar-marauder-1 es una nave completada. Copia la babosa, y de vuelta en la aplicación, visita /starships/lunar-marauder-1. Ya está. Para ver mejor la actualización, vamos a mostrar la fecha arrivedAt en la página de presentación.

En templates/starship/show.html.twig, copia estas etiquetas h4 y p. Pégalas a continuación. Actualiza el contenido de h4 a Arrived At y el de p a {{ ship.arrivedAt|ago }}:

43 lines | templates/starship/show.html.twig
// ... lines 1 - 4
{% block body %}
// ... lines 6 - 11
<div class="md:flex justify-center space-x-3 mt-5 px-4 lg:px-8">
// ... lines 13 - 15
<div class="space-y-5">
<div class="mt-8 max-w-xl mx-auto">
<div class="px-8 pt-8">
// ... lines 19 - 35
<h4 class="text-xs text-slate-300 font-semibold mt-2 uppercase">Arrived At</h4>
<p class="text-[22px] font-semibold">{{ ship.arrivedAt|ago }}</p>
</div>
</div>
</div>
</div>
{% endblock %}

Vuelve a la aplicación, actualiza y ¡listo! Esta nave está completada y llegó hace 1 mes.

Para registrar una nave cuando llega, creemos otro comando.

app:ship:check-in Comando

En tu terminal, ejecuta:

symfony console make:command

Para el nombre, utiliza app:ship:check-in.

Actualización de la plantilla de comandos

Abre la nueva clase de comando: src/Command/ShipCheckInCommand.php. Actualiza la descripción: Check-in ship:

59 lines | src/Command/ShipCheckInCommand.php
// ... lines 1 - 14
#[AsCommand(
name: 'app:ship:check-in',
description: 'Check-in a ship',
)]
class ShipCheckInCommand extends Command
// ... lines 20 - 59

y para el constructor, necesitamos lo mismo que para el comando eliminar. Ábrelo, copia el constructor y pégalo sobre ShipCheckInCommand::__construct():

59 lines | src/Command/ShipCheckInCommand.php
// ... lines 1 - 18
class ShipCheckInCommand extends Command
{
public function __construct(
private StarshipRepository $shipRepo,
private EntityManagerInterface $em,
) {
parent::__construct();
}
// ... lines 27 - 57
}

También encontraremos la nave por slug, así que copia el método configure() de ShipRemoveCommand y pégalo también:

59 lines | src/Command/ShipCheckInCommand.php
// ... lines 1 - 18
class ShipCheckInCommand extends Command
{
// ... lines 21 - 27
protected function configure(): void
{
$this
->addArgument('slug', InputArgument::REQUIRED, 'The slug of the starship')
;
}
// ... lines 34 - 57
}

Lógica del comando

La primera parte de execute(), encontrar la nave por slug, también es la misma, cópiala y pégala. Actualiza el comentario IO a "Comprobando en nave estelar...":

59 lines | src/Command/ShipCheckInCommand.php
// ... lines 1 - 18
class ShipCheckInCommand extends Command
{
// ... lines 21 - 34
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$slug = $input->getArgument('slug');
$ship = $this->shipRepo->findOneBy(['slug' => $slug]);
if (!$ship) {
$io->error('Starship not found.');
return Command::FAILURE;
}
$io->comment(sprintf('Checking-in starship: %s', $ship->getName()));
// ... lines 48 - 56
}
}

Es hora de la lógica real de "registro". Primero, actualiza la fecha de llegada a la hora actual con $ship->setArrivedAt(new \DateTimeImmutable('now')). A continuación, establece el estado en "esperando" con $ship->setStatus(StarshipStatusEnum::WAITING):

59 lines | src/Command/ShipCheckInCommand.php
// ... lines 1 - 18
class ShipCheckInCommand extends Command
{
// ... lines 21 - 34
protected function execute(InputInterface $input, OutputInterface $output): int
{
// ... lines 37 - 48
$ship->setArrivedAt(new \DateTimeImmutable('now'));
$ship->setStatus(StarshipStatusEnum::WAITING);
// ... lines 51 - 56
}
}

Estos campos se han actualizado en el objeto, pero aún no en la base de datos. Para ejecutar la consulta UPDATE, a continuación, llama, lo has adivinado, a $this->em->flush():

59 lines | src/Command/ShipCheckInCommand.php
// ... lines 1 - 18
class ShipCheckInCommand extends Command
{
// ... lines 21 - 34
protected function execute(InputInterface $input, OutputInterface $output): int
{
// ... lines 37 - 51
$this->em->flush();
// ... lines 53 - 56
}
}

Sólo flush()?

¡Espera, espera, espera! Cuando persistimos o eliminamos una entidad, teníamos que llamar a un método -como persist o remove en el gestor de entidades- para que Doctrine supiera nuestra intención. ¿Aquí no lo hacemos? ¡No! Doctrine es superinteligente. Arriba, cuando encontramos la entidad, Doctrine empezó a rastrearla. Cuando llamamos a flush(), ve que ha sido modificada y determina el mejor SQL para actualizar la base de datos. ¡Asombroso!

Por último, añade un mensaje de éxito "Nave estelar registrada":

59 lines | src/Command/ShipCheckInCommand.php
// ... lines 1 - 18
class ShipCheckInCommand extends Command
{
// ... lines 21 - 34
protected function execute(InputInterface $input, OutputInterface $output): int
{
// ... lines 37 - 53
$io->success('Starship checked-in.');
return Command::SUCCESS;
}
}

De vuelta a nuestra aplicación, ésta es la nave que queremos registrar. Copia el slug de la url.

Ejecuta el comando

En tu terminal, ejecuta el nuevo comando con:

symfony console app:ship:check-in

pega el slug y ¡ejecuta! ¡Éxito! De vuelta en la aplicación, actualiza. Ahora la nave está marcada como "esperando" y ha llegado hace 9 segundos. ¡Ha funcionado!

Vuelve a la lógica de registro dentro de ShipCheckInCommand. Estamos llamando a setters para actualizar dos campos. A continuación, vamos a encapsular esta lógica en un método de la entidadStarship.