Handling Object Dependencies
…$this->assertCount(0)
matches $enclosure->getDinosaurs().
Ok, good start! Next, inside Entity, create Enclosure. This will eventually
be a Doctrine entity, but don't worry about the annotations yet. Add a private $dinosaurs
property. And, like normal, add public function __construct() so that we can…
Integration Tests
…if you mock everything... there's
nothing really left to test
For example, how would you test that a complex query in a Doctrine repository works?
If you mock the database connection then... I guess you could test that the query
string you wrote looks…
More about List Field Types
…which controls that dataType config. There are a bunch of built-in types,
including all of the Doctrine field types and a few special fancy ones from EasyAdminBundle,
like toggle. The "toggle" type is actually super cool: it renders the field as
a little switch…
Override Controllers
…and I want you to know both.
Open the User entity. It has an updatedAt field:
To set this, we could use Doctrine lifecycle callbacks or a Doctrine event subscriber.
But, I want to see if we can set this instead, by hooking into EasyAdminBundle…
parameters.yml & %kernel.root_dir%
…the path from it.
Earlier, just to show off, we configured the DoctrineCacheBundle to store the
markdown cache in /tmp/doctrine_cache:
Referencing absolute paths is a little weird: why not just store this stuff in Symfony's
cache dir? Ok, ok, the bundle actually…
Parameters: The Variables of Configuration
…and set that
to a value. Why is this cool? Because you can then reuse that value in any other file
by saying %locale%.
Look under the doctrine key:
Hey, a bunch more, like %database_host% and %database_port%. These are set just
like locale…
Caching in the prod Environment Only
…the dev environment only?
Yes! Copy the doctrine_cache from config.yml and paste it into config_dev.yml.
Next, change type from file_system to array:
The array type is basically a "fake" cache: it won't ever store anything.
Yea, that's it…
Config.yml: Control Center for Services
…twig and doctrine -
corresponds to a bundle that is being configured:
All of this stuff under framework is configuration for the FrameworkBundle:
Everything under twig is used to control the behavior of the services from TwigBundle:
The job of a bundle is to give us…
Dynamic Roles
…ORM\Column annotation and set its type to json_array:
This is really cool because the $roles property will hold an array of roles,
but when we save, Doctrine will automatically json_encode that array and store
it in a single field. When we query…
The Mysterious "User Provider"
…the user provider
is responsible for loading the User from the session and making sure that it's
up to date. In Doctrine, we'll want our's to re-query for a fresh User object to
make sure all the data is still up…
Injecting the Cache Service
…Perfect!
We know this won't work: there is no get() function in this class. And more importantly,
we don't have access to the doctrine_cache.provider.my_markdown_cache service.
How can we get access? Dependency injection.
This time, add a second argument…
Custom Queries
…and-seek down
in the web debug toolbar. Ah, it turns out this is an EntityRepository object -
something from the core of Doctrine. And this class has the helpful methods on
it - like findAll() and findOneBy().
Ok, wouldn't it be sweet if we could…
Query for a List of Genuses
…create a new page that will show off all the genuses. Create
public function listAction() and give it a route path of /genus:
Remember, everything in Doctrine starts with the all-powerful entity manager. Just
like before, get it with $em = $this->getDoctrine()->getManager…
Database Migrations
…But this
bundle primarily gives us something different: a new set of console commands. Run
bin/console with no arguments:
Hiding in the middle is a whole group starting with doctrine:migrations. These
are our new best friend.
Our goal is to find a way…
Adding More Columns
…above each:
These tries to guess the right field type - but it's not always right. speciesCount
should clearly be an integer - set it to that. For a full-list of all the built-in
Doctrine types, check their docs. The most important are string…
Creating an Entity Class
…need a use statement for it. This
will look weird, but add a use for a Column class and let it auto-complete from
Doctrine\ORM\Mapping. Remove the Column part and add as ORM:
Every entity class will have that same use statement. Next…
Filters
…put anything in DiscontinuedFilter yet, but most of the work
is done. That ClassMetadata argument is your best friend: this is the Doctrine
object that knows everything about the entity we're querying for. You can
read your annotation mapping config, get details on associations…
Symfony Overlord: The Service Container
…With such a tiny list, it’s easy
to spot the entity manager service: doctrine.orm.entity_manager. This
is the “name” of the service and we use it to get this object out of the
service container.
We’ve been getting the entity manager…
More with ManyToMany: Avoiding Duplicates
…an error!
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry
‘4-4’ for key ‘PRIMARY’
Our User is once again added as an attendee to the Event. And when Doctrine saves,
it tries to add a second row to the join table. Not cool!
Adding…
ManyToMany Relationship
…
Like with a ManyToOne, we just need an annotation that tells
Doctrine what type of association this is and what entity it relates to:
// src/Yoda/EventBundle/Entity/Event.php
// ...
/**
@ORM\ManyToMany(targetEntity="Yoda\UserBundle\Entity\User")
/
protected $attendees;
Whenever you have a relationship that…
x
1000+