This course is still being released! Check back later for more chapters.
Inserting Data via 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 SubscribeWe have our database table, but now we need some data! When working in your development environment, it's useful to have a set of fake data to seed you database: stuff you can play around with while building. We call this data fixtures.
In our case, it would be great to pre-fill our table with some Starships! Doctrine even has a package adding this fake fixtures data! At your terminal, run:
composer require --dev orm-fixtures
We used --dev
because we only need fixtures in our development environment. Scroll up to see what was installed: doctrine/data-fixtures
and doctrine-fixtures-bundle
. Run
git status
to see what the recipes added. Standard Flex stuff, added a bundle, but also this src/DataFixtures
directory. Let's check that out: open src/DataFixtures/AppFixtures.php
. This load()
method is where we can create our fixtures. Delete what's there so we can start fresh.
Create Entities
To add entities to the database no matter where you are, it's refreshingly simple! First, create the object like normal: $ship1 = new Starship()
- the one from App\Entity
.
// ... lines 1 - 9 | |
class AppFixtures extends Fixture | |
// ... line 11 | |
public function load(ObjectManager $manager): void | |
{ | |
$ship1 = new Starship(); | |
// ... lines 15 - 35 | |
} | |
} |
In a previous episode, we created this StarshipRepository
service in src/Model/
. Open that up. We have a findAll()
method that creates these Starship objects on the fly. We'll use this data for our fixtures!
Copy the second argument of the first Starship - that's the name. Back in AppFixtures
, call $ship1->setName('USS LeafyCruiser (NCC-0001)')
. Do the same for $class
: $ship1->setClass('Garden')
, $captain
: $ship1->setCaptain('John Luke Pickles')
, $status
: $ship1->setStatus(StarshipStatusEnum::IN_PROGRESS)
and don't forget to import the enum. Finally, $arrivedAt
: $ship1->setArrivedAt(new \DateTimeImmutable('-1 day'))
.
// ... lines 1 - 9 | |
class AppFixtures extends Fixture | |
// ... line 11 | |
public function load(ObjectManager $manager): void | |
{ | |
// ... line 14 | |
$ship1->setName('USS LeafyCruiser (NCC-0001)'); | |
$ship1->setClass('Garden'); | |
$ship1->setCaptain('Jean-Luc Pickles'); | |
$ship1->setStatus(StarshipStatusEnum::IN_PROGRESS); | |
$ship1->setArrivedAt(new \DateTimeImmutable('-1 day')); | |
// ... lines 20 - 35 | |
} | |
} |
For the other two ships, I'll copy and paste some code from the tutorial/
directory.
// ... lines 1 - 9 | |
class AppFixtures extends Fixture | |
// ... line 11 | |
public function load(ObjectManager $manager): void | |
{ | |
// ... lines 14 - 20 | |
$ship2 = new Starship(); | |
$ship2->setName('USS Espresso (NCC-1234-C)'); | |
$ship2->setClass('Latte'); | |
$ship2->setCaptain('James T. Quick!'); | |
$ship2->setStatus(StarshipStatusEnum::COMPLETED); | |
$ship2->setArrivedAt(new \DateTimeImmutable('-1 week')); | |
$ship3 = new Starship(); | |
$ship3->setName('USS Wanderlust (NCC-2024-W)'); | |
$ship3->setClass('Delta Tourist'); | |
$ship3->setCaptain('Kathryn Journeyway'); | |
$ship3->setStatus(StarshipStatusEnum::WAITING); | |
$ship3->setArrivedAt(new \DateTimeImmutable('-1 month')); | |
// ... lines 34 - 35 | |
} | |
} |
We now have three ship objects, but nothing has been saved - or persisted to the database yet. But interesting, Doctrine passes us an ObjectManager
. This is the heart of Doctrine. We'll use it to save, fetch, update, and delete objects, our entities, from the database. What an overachiever!
Persist Entities
To use it, after we've created our ship objects, write $manager->persist($ship1)
, $manager->persist($ship2)
, and $manager->persist($ship3)
. But persist()
doesn't actually insert them yet: it just queues them to be saved.
// ... lines 1 - 9 | |
class AppFixtures extends Fixture | |
// ... line 11 | |
public function load(ObjectManager $manager): void | |
{ | |
// ... lines 14 - 34 | |
$manager->persist($ship1); | |
$manager->persist($ship2); | |
$manager->persist($ship3); | |
// ... lines 38 - 39 | |
} | |
} |
Flush
To execute some INSERT queries and get these ships docked, write $manager->flush()
.
// ... lines 1 - 9 | |
class AppFixtures extends Fixture | |
// ... line 11 | |
public function load(ObjectManager $manager): void | |
{ | |
// ... lines 14 - 38 | |
$manager->flush(); | |
} | |
} |
flush()
is really cool: it looks at all the objects that are queued to be persisted and writes them to the database with an efficient SQL query. In this case, it will insert all three Starships in one query. Super cool!
Load Fixtures
Fixtures done! How do we execute this code? Run:
symfony console doctrine:fixtures:load
It's double-checking that we really want to load our fixtures because it will also erase all existing data. Choose yes
and... Success?
Run that raw SQL query again:
symfony console doctrine:query:sql 'SELECT * FROM starship'
We have ships! Awesome!
Phew, we now have a database with data! Next, we'll refactor our app's controllers to pull Starships from our database and show them on the page. This will be much easier than you might imagine!