Login to bookmark this video
Buy Access to Course
04.

Establecer la relación

|

Share this awesome video!

|

Vale, pero ¿cómo establecemos realmente la relación? ¿Cómo decimos

¿Este StarshipPart pertenece a este Starship?

Hasta ahora, hemos estado trabajando en AppFixtures con Foundry. Volveremos a Foundry dentro de un rato, pero volvamos a la vieja escuela por un minuto para ver cómo funciona todo esto.

Empieza con new Starship()... luego pegaré algo de código para establecer las propiedades necesarias. A continuación, añade $manager->persist($starship):

58 lines | src/DataFixtures/AppFixtures.php
// ... lines 1 - 4
use App\Entity\Starship;
// ... lines 6 - 12
class AppFixtures extends Fixture
{
public function load(ObjectManager $manager): void
{
StarshipFactory::createOne([
// ... lines 18 - 22
]);
$starship = new Starship();
$starship->setName('USS Taco Tuesday');
$starship->setClass('Tex-Mex');
$starship->checkIn();
$starship->setCaptain('James T. Nacho');
$manager->persist($starship);
// ... lines 31 - 55
}
}

A continuación crea un nuevo StarshipPart y al igual que antes, pegaré código para rellenar las propiedades. A continuación, asegúrate de que esto se guarda con $manager->persist($part), y por último, $manager->flush():

58 lines | src/DataFixtures/AppFixtures.php
// ... lines 1 - 4
use App\Entity\Starship;
use App\Entity\StarshipPart;
// ... lines 7 - 12
class AppFixtures extends Fixture
{
public function load(ObjectManager $manager): void
{
// ... lines 17 - 24
$starship = new Starship();
$starship->setName('USS Taco Tuesday');
$starship->setClass('Tex-Mex');
$starship->checkIn();
$starship->setCaptain('James T. Nacho');
$manager->persist($starship);
$part = new StarshipPart();
$part->setName('spoiler');
$part->setNotes('There\'s no air drag in space, but it looks cool.');
$part->setPrice(500);
$manager->persist($part);
$manager->flush();
// ... lines 38 - 55
}
}

Foundry suele llamar a persist() y flush() por nosotros. Pero como estamos en modo manual, tenemos que hacerlo nosotros.

Tenemos un Starship y un StarshipPart, pero aún no están relacionados. Pff, intenta cargarlos de todas formas. Dirígete a tu terminal y ejecuta:

symfony console doctrine:fixtures:load

Rutro:

starship_id no puede ser nulo en la tabla starship_part.

¿Por qué es necesaria esa columna? En StarshipPart, la propiedad starship tiene un atributo ManyToOney otro JoinColumn():

86 lines | src/Entity/StarshipPart.php
// ... lines 1 - 10
class StarshipPart
{
// ... lines 13 - 28
#[ORM\ManyToOne(inversedBy: 'parts')]
#[ORM\JoinColumn(nullable: false)]
private ?Starship $starship = null;
// ... lines 32 - 84
}

Esto nos permite controlar la columna de clave foránea: nullable: false significa que todoStarshipPart debe pertenecer a un Starship.

Asignación de la pieza a la nave

Entonces, ¿cómo decimos que esta pieza pertenece a este Starship? La respuesta es maravillosamente sencilla. En cualquier lugar antes de flush(), decimos$part->setStarship($starship):

59 lines | src/DataFixtures/AppFixtures.php
// ... lines 1 - 12
class AppFixtures extends Fixture
{
public function load(ObjectManager $manager): void
{
// ... lines 17 - 36
$part->setStarship($starship);
$manager->flush();
// ... lines 39 - 56
}
}

Eso es todo. Con Doctrine, no establecemos ninguna propiedad starship_id ni siquiera pasamos un ID, como $starship->getId(). No Fijamos objetos. Doctrine se encarga de los aburridos detalles de la inserción: primero guarda el Starship, luego utiliza su nuevo id para establecer la columna starship_id en la tabla starship_part.

¡Qué listo!

Prueba de nuevo las fijaciones:

symfony console doctrine:fixtures:load

¡Sin errores! Comprueba las cosas:

symfony console doctrine:query:sql 'SELECT * FROM starship_part'

¡Et voila! Ahí está nuestra pieza única, felizmente vinculada a starship_id 75. Compruébalo:

symfony console doctrine:query:sql 'SELECT * FROM starship WHERE id = 75'

Ahí está: Starship id 75 tiene un StarshipPart id 1. ¡Somos geniales!

Doctrine: trabaja con objetos, no con IDs

Estas son las conclusiones: con las relaciones Doctrine, estás en el mundo de los objetos. Olvídate de los ID. Doctrine se encarga de esa parte por ti. Tú fijas el objeto y Doctrine hace el resto.

Pero ugh, esto es mucho trabajo en AppFixtures para crear un únicoStarship y un único StarshipPart. Así que, a continuación, volvamos a utilizar Foundry para crear una flota de naves y un montón de piezas y enlazarlas todas de una sola vez. Aquí es donde Foundry brilla de verdad.