Fetching a Relation's Data
… Instead, pass the Starship object itself. You could pass the id if
you're feeling lazy, but in the spirit of Doctrine, relationships, and
thinking about objects, passing the entire Starship object is the way to go.
Let's debug and see what we've…
A World without Build Systems?
…and... hello Mixed Vinyl! But wow is this thing weird and ugly-looking.
This is a Symfony 6.3 project - the same project we've built in the Symfony series.
It has Doctrine installed... but there's nothing particularly special about it, and
right now…
Droid Entity for the ManyToMany Relationship
…to generate the migration and run it:
Go take a peek. No surprises here. So... run it:
symfony console doctrine:migrations:migrate
And... we've got a shiny new droid table in the database. It's not yet
in a relationship with ship, but hey…
Setting Many To Many Relations
…the flush, remove an assignment:
$starship->removeDroid($droid1):
Reload the fixtures and check out the join table.
Only two rows remain! Doctrine removed the row for our removed droid.
One final touch on ManyToMany — remember when we discussed owning
versus inverse sides of a relationship?…
Many-To-Many Relationship
…database: with a join table.
The real magic of Doctrine is that we only need to think about objects. A Starship
object has many Droid objects, and a Droid object has many Starship objects.
Doctrine handles the tedious details of saving that relationship to the…
Criteria: Filter Relation Collections
…There it
is. Below, add a new method called getFortuneCookiesStillInProduction(). This,
like the normal method, will return a Doctrine Collection. And... just to help
my editor, copy the @return doc above to say that this is a Collection of
FortuneCookie objects.
So... what do we…
Joining Across a Many-to-Many Relationship
…add a leftJoin(). But we're not going to think about
the join table or the database. Nope, focus only on the relationships in Doctrine.
So we're joining across s, which is our starship, and droids, the property
that has the ManyToMany relationship to…
Using RAND() or Other Non-Supported Functions
…t change anything in our app... it just adds a bunch of code
that we can activate for any functions that we want. To do that, back over in
config/packages/doctrine.yaml, somewhere under orm, say dql. There are a bunch
of different categories…
andWhere() and orWhere()
…andWhere()
is always ok - even if this is the first WHERE clause... and we don't really
need the "and" part. Doctrine is smart enough to figure that out.
What's wrong with ->where()? Well, if you added a WHERE clause to
your QueryBuilder earlier…
Filters: Searching Results
…since we're using the Doctrine ORM -
because we want to allow the user to filter on a boolean field.
The second thing you need top pass is properties set to an array of which fields
or properties you want to use this filter on…
Pagination & Foundry Fixtures
…method. All we need
is: DragonTreasureFactory::createMany(40) to create a healthy trove of 40
treasures:
Let's try this thing! Back at your terminal, run:
symfony console doctrine:fixtures:load
Say "yes" and... it looks like it worked! Back on our API docs, refresh…
Initialize the Bundle
…bundles already exist out there that are capable of this, but I wanted to approach
it fresh, with a slightly different perspective.
So that's what our bundle will do: translate Doctrine entities!
Let's get started!
Jump over to the code for this project…
Cascade Persist
…and... we can now see when each droid was assigned.
That's it, friends! We've explored the deepest corners of Doctrine
relationships, even the elusive many-to-many with extra fields. As always,
if you have questions, drop them in the comments below. We…
Re-adding addDroid(): Hide that Join Entity!
…This one is pretty common in Doctrine,
though not always easy to understand:
A new entity was found through the relationship Starship#starshipDroids
that was not configured to cascade persist for the entity StarshipDroid.
This is a very fancy way of saying we've created…
WHERE IN()
…but inside of that, instead of a comma-separated list, you'll set an
array. Doctrine will transform that for us.
And now... nice! Once you know how it works, it's just that easy.
Next: You're probably familiar with the RAND() function for…
SELECT the SUM (or COUNT)
…object.
This is interesting too! In SQL, we would normally say something like
WHERE fortuneCookie.categoryId = and then the integer ID. But in Doctrine, we don't
think about the tables or columns: we focus on the entities. And, there is no
categoryId property…
Bonus: Custom DQL Function
…on.
It's subtle, but look at the WHERE clause: s0_.id = ?. This s0_ is an
internal SQL table alias Doctrine uses - it's our starship table. I expected
this to use our discriminator column, but it's using the id. I guess when…
Resetting the Database
…method and run code here that does that. Fortunately,
we don't need to because there are multiple libraries that already solve this
problem. My favorite is Foundry.
Run:
If you watched our Doctrine tutorial, you'll remember Foundry! But you may not
know about…
Removing Items from a Collection
…the dragonTreasures
property. After cascade, add one more option here: orphanRemoval: true.
This tells Doctrine that if any of these dragonTreasures become "orphaned" - meaning
they no longer have any owner - they should be deleted.
Let's try it. When we hit "Execute" again... got it…
Adding Items to a Collection Property
…to be this object. That's important
because of how Doctrine handles relationships: setting the owner sets what's called
the "owning" side of the relationship. Basically, without this, Doctrine wouldn't
save this change to the database.
The takeaway is that, thanks to addDragonTreasure…
x
1000+