Simple Doctrine Data Fixtures
Keep on Learning!
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 Subscribe"Data fixtures" is the name given to dummy data that you add to your app while developing or running tests to make life easier. It's a lot nicer to work on a new feature when you actually have decent data in your database. We created some data fixtures, in a sense, via this new
action. But Doctrine has a system specifically designed for this.
Installing DoctrineFixturesBundle
Search for "doctrinefixturesbundle" to find its GitHub repository. And you can actually read its documentation over on Symfony.com. Copy the install line and, at your terminal, run it:
composer require --dev orm-fixtures
orm-fixtures
is, of course, a Flex alias, in this case, to doctrine/doctrine-fixtures-bundle
. And... done! Run
git status
to see that this added a bundle, as well as a new src/DataFixtures/
directory. Go open that up. Inside, we have a single new file called AppFixtures.php
.
// ... lines 1 - 7 | |
class AppFixtures extends Fixture | |
{ | |
public function load(ObjectManager $manager): void | |
{ | |
// $product = new Product(); | |
// $manager->persist($product); | |
$manager->flush(); | |
} | |
} |
DoctrineFixturesBundle is a delightfully simple bundle. It gives us a new console command called doctrine:fixtures:load
. When we run this, it will empty our database and then execute the load()
method inside of AppFixtures
. Well, it will actually execute the load()
method on any service we have that extends this Fixture
class. So we could have multiple classes in this directory if we want.
If we run it right now... with an empty load()
method, it clears our database, calls that blank method, and... the result over on the "Browse" page is that we have nothing!
php bin/console doctrine:fixtures:load
Filling in the load() Method
That's not very interesting, so let's go fill in that load()
method! Start in MixController
: steal all of the VinylMix
code... and paste it here. Hit "Ok" to add the use
statement.
// ... 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 |
Notice the load()
method accepts some ObjectManager
argument. That's actually the EntityManager
, since we're using the ORM. If you look down here, it already has the flush()
call. The only thing we're missing is the persist()
call: $manager->persist($mix)
.
// ... lines 1 - 10 | |
public function load(ObjectManager $manager): void | |
{ | |
// ... lines 13 - 19 | |
$manager->persist($mix); | |
// ... lines 21 - 22 | |
} | |
// ... lines 24 - 25 |
So the variable is called $manager
here... but these two lines are exactly what we have our controller: persist()
and flush()
.
Try the command again:
php bin/console doctrine:fixtures:load
It empties the database, executes our fixtures, and we have... one new mix!
Okay, this is kind of cool. We have a new bin/console
command to load stuff. But for developing, I want a really rich set of data fixtures, like... maybe 25 mixes. We could add those by hand here... or even create a loop. But there's a better way, via a library called "Foundry". Let's explore it next!
With
symfony console doctrine:fixtures:load --append
it will append data.