If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login Subscribese denomina "Data Fixtures" a los datos ficticios que añades a tu aplicación mientras desarrollas o ejecutas pruebas para facilitarte la vida. Es mucho más agradable trabajar en una nueva función cuando realmente tienes datos decentes en tu base de datos. Hemos creado algunos datos fijos, en cierto sentido, mediante esta acción de new
. Pero Doctrine tiene un sistema específicamente diseñado para esto.
Busca "doctrinefixturesbundle" para encontrar su repositorio en GitHub. Y puedes leer su documentación en Symfony.com. Copia la línea de instalación y, en tu terminal, ejecútala:
composer require --dev orm-fixtures
orm-fixtures
es, por supuesto, un alias de Flex, en este caso, adoctrine/doctrine-fixtures-bundle
. Y... ¡listo! Ejecuta
git status
para ver que esto ha añadido un bundle, así como un nuevo directorio src/DataFixtures/
. Ve a abrirlo. Dentro, tenemos un único archivo nuevo llamado AppFixtures.php
.
... lines 1 - 7 | |
class AppFixtures extends Fixture | |
{ | |
public function load(ObjectManager $manager): void | |
{ | |
// $product = new Product(); | |
// $manager->persist($product); | |
$manager->flush(); | |
} | |
} |
DoctrineFixturesBundle es un bundle deliciosamente sencillo. Nos proporciona un nuevo comando de consola llamado doctrine:fixtures:load
. Cuando lo ejecutemos, vaciará nuestra base de datos y luego ejecutará el método load()
dentro de AppFixtures
. Bueno, en realidad ejecutará el método load()
en cualquier servicio que tengamos que extienda esta clase Fixture
. Así que podemos tener varias clases en este directorio si queremos.
Si lo ejecutamos ahora mismo... con un método load()
vacío, limpia nuestra base de datos, llama a ese método vacío y... ¡el resultado en la página "Examinar" es que no tenemos nada!
php bin/console doctrine:fixtures:load
¡Eso no es muy interesante, así que vamos a rellenar ese método load()
! Empieza enMixController
: roba todo el código de VinylMix
... y pégalo aquí. Pulsa "Ok" para añadir la declaración use
.
... lines 1 - 10 | |
public function load(ObjectManager $manager): void | |
{ | |
$mix = new VinylMix(); | |
$mix->setTitle('Do you Remember... Phil Collins?!'); | |
$mix->setDescription('A pure mix of drummers turned singers!'); | |
$genres = ['pop', 'rock']; | |
$mix->setGenre($genres[array_rand($genres)]); | |
$mix->setTrackCount(rand(5, 20)); | |
$mix->setVotes(rand(-50, 50)); | |
$manager->flush(); | |
} | |
... lines 23 - 24 |
Fíjate en que el método load()
acepta algún argumento de ObjectManager
. En realidad es el EntityManager
, ya que estamos utilizando el ORM. Si miras aquí abajo, ya tiene la llamada flush()
. Lo único que nos falta es la llamada persist()
:$manager->persist($mix)
.
... lines 1 - 10 | |
public function load(ObjectManager $manager): void | |
{ | |
... lines 13 - 19 | |
$manager->persist($mix); | |
... lines 21 - 22 | |
} | |
... lines 24 - 25 |
Así que la variable se llama aquí $manager
... pero estas dos líneas son exactamente las que tiene nuestro controlador: persist()
y flush()
.
Prueba de nuevo el comando:
php bin/console doctrine:fixtures:load
Vacía la base de datos, ejecuta nuestros accesorios y tenemos... ¡una nueva mezcla!
Vale, esto es genial. Tenemos un nuevo comando bin/console
para cargar cosas. Pero para el desarrollo, quiero un conjunto realmente rico de datos de fijos, como... tal vez 25 mezclas. Podríamos añadirlas a mano aquí... o incluso crear un bucle. Pero hay una forma mejor, a través de una biblioteca llamada "Foundry". ¡Vamos a explorarla a continuación!
Fixture
classes probably should be excluded from deployment, if composer install --no-dev
is used on the server?
Hey Andrey,
Yes, you could exclude or remove the fixtures on your production server for an extra (but tiny) performance boost.
Cheers!
Unrelated question – why am I always switched to Spanish version of SymfonyCasts, when I click on a reply notifications under the bell icon? :)
Thanks, but it's more important than performance boost. Class AppFixtures
extends a class which will not exist in production environment.
Yea, that's a good point, but as long as nothing in your production code depends on those classes, you should be fine. Otherwise, you'll need to find a way to remove them from production. An easy way would be just to add a specific prod config to exclude the "DataFixtures" directory from being autoregistered.
Cheers!
// composer.json
{
"require": {
"php": ">=8.1",
"ext-ctype": "*",
"ext-iconv": "*",
"babdev/pagerfanta-bundle": "^3.7", // v3.7.0
"doctrine/doctrine-bundle": "^2.7", // 2.7.0
"doctrine/doctrine-migrations-bundle": "^3.2", // 3.2.2
"doctrine/orm": "^2.12", // 2.12.3
"knplabs/knp-time-bundle": "^1.18", // v1.19.0
"pagerfanta/doctrine-orm-adapter": "^3.6", // v3.6.1
"pagerfanta/twig": "^3.6", // v3.6.1
"sensio/framework-extra-bundle": "^6.2", // v6.2.6
"stof/doctrine-extensions-bundle": "^1.7", // v1.7.0
"symfony/asset": "6.1.*", // v6.1.0
"symfony/console": "6.1.*", // v6.1.2
"symfony/dotenv": "6.1.*", // v6.1.0
"symfony/flex": "^2", // v2.2.2
"symfony/framework-bundle": "6.1.*", // v6.1.2
"symfony/http-client": "6.1.*", // v6.1.2
"symfony/monolog-bundle": "^3.0", // v3.8.0
"symfony/proxy-manager-bridge": "6.1.*", // v6.1.0
"symfony/runtime": "6.1.*", // v6.1.1
"symfony/twig-bundle": "6.1.*", // v6.1.1
"symfony/ux-turbo": "^2.0", // v2.3.0
"symfony/webpack-encore-bundle": "^1.13", // v1.15.1
"symfony/yaml": "6.1.*", // v6.1.2
"twig/extra-bundle": "^2.12|^3.0", // v3.4.0
"twig/twig": "^2.12|^3.0" // v3.4.1
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.2
"symfony/debug-bundle": "6.1.*", // v6.1.0
"symfony/maker-bundle": "^1.41", // v1.44.0
"symfony/stopwatch": "6.1.*", // v6.1.0
"symfony/web-profiler-bundle": "6.1.*", // v6.1.2
"zenstruck/foundry": "^1.21" // v1.21.0
}
}
With
symfony console doctrine:fixtures:load --append
it will append data.