Parte Entidad
Ya tenemos naves estelares que aparecen en la página de inicio gracias a la entidadStarship
que construimos en el último tutorial. Pero ahora ha llegado el momento de mejorar. Necesitamos hacer un seguimiento de las piezas individuales utilizadas en cada Starship
. Éste es el plan: cada parte pertenecerá exactamente a unStarship
, y cada Starship
tendrá muchas partes. Pero antes de sumergirnos en las relaciones, tenemos que empezar por lo más sencillo: ¡necesitamos una nueva entidad para hacer un seguimiento de estas partes! Enciende tu terminal, abre una nueva pestaña (ya que nuestro servidor está zumbando en la otra), y ejecuta:
symfony console make:entity
Llámalo StarshipPart
, omite la emisión, y dale unos cuantos campos: name
será una cadena y no será anulable, price
será un número entero (en créditos, por supuesto), y tampoco será anulable. Por último, añade un campo notes
que será de tipo text
(por lo que puede ser más largo), y será anulable. Una vez que hayas añadido estos campos, crea una nueva migración para la entidad copiando y pegandosymfony console make:migration
.
Ejecutar migraciones y añadir marcas de tiempo
Ahora, si compruebas tus migraciones, verás sólo la nueva que hemos creado: He limpiado las migraciones antiguas del curso pasado.
// ... lines 1 - 12 | |
final class Version20250306155858 extends AbstractMigration | |
{ | |
// ... lines 15 - 19 | |
public function up(Schema $schema): void | |
{ | |
// this up() migration is auto-generated, please modify it to your needs | |
$this->addSql('CREATE TABLE starship_part (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, name VARCHAR(255) NOT NULL, price INT NOT NULL, notes TEXT DEFAULT NULL, PRIMARY KEY(id))'); | |
} | |
// ... lines 25 - 30 | |
} |
Así que ésta es toda sobre StarshipPart
. Ejecútala con:
symfony console doctrine:migrations:migrate
¡La tabla está en la base de datos! Pero hay dos campos que me gusta añadir a todas mis entidades: createdAt
y updatedAt
. Puedes verlos dentro de Starship
, bajo TimestampableEntity
.
// ... lines 1 - 11 | |
class Starship | |
{ | |
use TimestampableEntity; | |
// ... lines 15 - 137 | |
} |
Cópialo y pégalo justo encima de StarshipPart
. Ambas propiedades se establecen automáticamente gracias a una biblioteca que instalamos en el último tutorial. Y como hemos añadido dos campos nuevos, ¡necesitamos una migración!
symfony console make:migration
Pues migra:
symfony console doctrine:migrations:migrate
Utilizar fábricas para crear objetos ficticios
En el último tutorial, utilizamos una biblioteca genial llamada Foundry
para crear rápidamente un montón de datos ficticios. Vamos a hacer lo mismo conStarshipPart
. El paso 1 -ya que aún no tenemos una- es generar una fábrica para la entidad con:
symfony console make:factory
Ve a verlo en src/Factory/StarshipPartFactory.php
. Añade algunos valores por defecto para cada campo, pero podemos hacerlo más interesante. En la parte superior de StarshipPartFactory
, pegaré algo de código con partes de ejemplo (puedes cogerlo del bloque de código de esta página). Sustituye también el retorno en defaults()
por código que utilice esos datos.
// ... lines 1 - 10 | |
final class StarshipPartFactory extends PersistentProxyObjectFactory | |
{ | |
private static array $partIdeas = [ | |
'warp core' => 'looks cool AND zoom', | |
'shield generator' => 'in case you run into any Borg', | |
'captain\'s chair' => 'just slightly more comfortable than the others', | |
'fuzzy dice' => 'obviously', | |
'photon torpedoes' => 'for when the fuzzy dice don\'t work', | |
'holodeck' => 'parental controls? No way!', | |
'Tactical Whoopee Cushion Array' => 'can\'t beat them? Embarrass them!', | |
'Temporal Seat Warmers' => 'warm your seat before you sit down', | |
'Food Replicator' => 'Earl Grey, hot', | |
'Self-Destruct Button Cover' => 'for when you have a cat', | |
'Redshirt Dispenser' => 'Instantly replenishes expendable crew members.', | |
]; | |
// ... lines 26 - 44 | |
protected function defaults(): array|callable | |
{ | |
$randomPartKey = self::faker()->randomKey(self::$partIdeas); | |
$randomPart = [$randomPartKey, self::$partIdeas[$randomPartKey]]; | |
return [ | |
'name' => $randomPart[0], | |
'notes' => $randomPart[1], | |
'price' => self::faker()->randomNumber(5), | |
]; | |
} | |
// ... lines 56 - 65 | |
} |
Por último, utiliza esto en los accesorios. En la parte inferior, crea 50 piezas aleatorias utilizandoStarshipPartFactory::createMany(50)
.
// ... lines 1 - 10 | |
class AppFixtures extends Fixture | |
{ | |
public function load(ObjectManager $manager): void | |
{ | |
// ... lines 15 - 38 | |
StarshipFactory::createMany(20); | |
StarshipPartFactory::createMany(50); | |
} | |
} |
De nuevo en el terminal, ejecuta:
symfony console doctrine:fixtures:load
Y comprueba las nuevas piezas con:
symfony console doctrine:query:sql
Y luego select * from starship_part
Y con sólo unas pocas líneas de delicioso código, tenemos 50 piezas aleatorias en la base de datos. A continuación: empecemos a vincular estas piezas a sus respectivas naves creando nuestra primera relación: la importantísima relación ManyToOne
.