Deployment
…Update your database schema. The easy, but maybe dangerous way is with
the schema update console command:
php app/console doctrine:schema:update --force
Why dangerous? Let’s say you rename a property from name to firstName.
Instead of renaming the column, this task may…
Dependency Inject All the Things
…the router
service. So how can we get the router service inside EventReportManager?
You know the secret: dependency injection.
Add a second constructor argument and a second class property:
// src/Yoda/EventBundle/Reporting/EventReportManager.php
// ...
use Doctrine\ORM\EntityManager;
use Symfony\Component\Routing\Router;
class…
Configuration Loading and Type-Hinting
…mind trick ... I mean
auto-complete the use statement for me. It’s lazy, but it almost always works:
// src/Yoda/EventBundle/Reporting/EventReportManager.php
// ...
use Doctrine\ORM\EntityManager;
class EventReportManager
{
}
If you’re not too comfortable with this, don’t worry. This is optional…
Your Very First Service
…we don’t extend anything and we
don’t magically have access to this Doctrine object.
The code inside EventReportManager is dependent on this “doctrine”
object. Well, more specifically, it’s dependent on Doctrine’s entity manager.
The fix for our puzzle is to “inject…
Using the ManyToMany so Users can Attend an Event
…that we show 1 attending means that the database relationship was
stored correctly. We can prove it by querying for the join table:
php app/console doctrine:query:sql "SELECT * FROM event_user"
Yep, we see one row that links our user to this event.…
Using PHPDoc for Auto-Completion
…better than nothing.
But first, update your test database for our latest schema changes:
php app/console doctrine:schema:update --force --env=test
We need this because we configured our project in episode 2 to use an entirely
different database for testing.
./bin/phpunit -c app/
Server-Side Validation
…It takes two options: the field
that should be unique followed by a message. Add a constraint for both the
username and the email:
// src/Yoda/UserBundle/Entity/User.php
// ...
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
@ORM\Table(name="yoda_user")
@ORM\Entity(repositoryClass=…
FOSUserBundle
…stored in the database. Let’s create
a new bundle called UserBundle to house the new entity. Instead of using
the doctrine:generate:bundle task, I’ll just create a UserBundle
and make sure there’s a properly-named bundle class inside. Don’t forget…
Content Browser
…when we try the page, we're greeted with an error!
Netgen Content Browser backend for doctrine_recipe value type does not exist.
Yep! We need to implement a class that helps Layouts browse our recipes. That's
called a "content browser".
Adding a content…
Item View Template
…match one piece of config, like
this template, with some other piece of config, like the doctrine_recipe value
type. There are a finite number of these matchers, and we're going to see the most
important ones along the way. So don't worry…
Value Converter
…s an instanceof Recipe:
Second, for getValueType(), return the internal key of our value type:
doctrine_recipe:
Next is getId()... and we're literally going to return our ID with
$object->getId():
We don't have autocomplete on this, but we know this object will…
Enhanced Docker Integration & Testing Emails
…Finally, just like normal, thanks to our
config/packages/doctrine.yaml configuration, the DATABASE_URL environment variable
is used to talk to the database. So the Symfony binary plus Docker is a nice way
to quickly and easily boot up external services like a database…
Recipe Upgrades with recipes:update
…the recipe relate to the config files, and I bet you can see
what's happening. It deleted two environment-specific config files and updated
the main one. Hmm.
Open config/packages/doctrine.yaml. Sure enough, at the bottom, we see when@test
and when…
Foundry Tricks
…Faker again! self::faker()->numberBetween(1, 4) and then true
to return this as a string.
Let's take this for a test drive! Find your terminal and reload the fixtures with:
symfony console doctrine:fixtures:load
Go check the homepage and... yea!
Oh, but…
Update Query & Rich vs Anemic Models
…whenever we need to save something in Doctrine, we need the
entity manager.
Add another argument: EntityManagerInterface $entityManager.
Then, below, replace the dd($question) with $entityManager->flush().
Done! Seriously! Doctrine is smart enough to realize that the Question object
already exists in the database and…
Custom Repository Class
…here.
We'll see this idea of custom entity methods later.
At the bottom, there's one more link: question.slug.
Done! Doctrine makes it easy to query for data and Twig makes it easy to render.
Go team! At the browser, refresh and... cool…
Fetching Data & The Repository
… Refresh and... woohoo! This gives us a Question
object. Doctrine finds the matching row of data and uses that to populate an
object, which is beautiful.
The repository has a number of other methods on it. For example, findOneBy()
returns a single object and findBy…
docker-compose Env Vars & Symfony
…For example, because this service is called database - we technically could have
called it anything - the Symfony binary is already exposing an environment variable
called DATABASE_URL: the exact environment variable that Doctrine is looking
for.
I'll show you exactly what I mean. First…
Validation Auto-Mapping
…How the
heck did that work? The system - validation auto-mapping - automatically adds
sensible validation constraints based off of your Doctrine metadata. The
Doctrine Column annotation has a nullable option and its default value is
nullable=false:
In other words, the title column is required in…
Spotting Heavy Object Instantiation
…to instantiate Doctrine's EntityManager object.
I know, we don't often think about how much time or how much memory it takes to
instantiate an object, but it can sometimes be a problem. The next function
call is for the instantiation of Doctrine's…
x
1000+