This Chapter isn't quite ready yet
Rest assured, the gnomes are hard at work on completing this video
We need the ability to add tags to each
Article. And that means, we need a new
relationship! Like always, we could add this by hand. But, the generator can help
us. At your terminal, run:
php bin/console make:entity
But, hmm. Which entity should we update? We could add the relationship to the
Article class and point it at
Tag... or I guess we could add the relationship
Tag class and point it at
And... yea! We could choose to update either class. There is a subtle difference
that we'll learn about soon. But, don't worry about it et. Choose
the property name, use
tags. Remember, we need to stop thinking about the database
and only think about our objects. In PHP, I want an
Article object to have many
Tag objects. So, the property should be called
For type, use the fake
relation type: that will activate a wizard to help us.
We want to relate this to
Tag and... perfect! Here is our menu of relationship
options! I already hinted that this will be a
ManyToMany relationship. Let's look
at the description to see if it fits. Each article can have many tags. And, each
tag can relate to many articles. Yep, that's us! This is a ManyToMany relationship.
And just like last time, it asks us if we also want to map the other side of
the relationship. This is optional, and will only be for convenience. If we
map this side, we'll be able to say
$tag->getArticles(). That may or may not
be useful for us, but let's say yes. Call the field
articles, because it will
hold an array of
And, that's it! Hit enter to finish.
Woohoo! So exciting: let's see what changes this made. Open
Article first. Yes!
Here is our new
tags property: it's a ManyToMany that points to the
And, like we saw earlier with comments, whenever you have a relationship that holds
multiple objects, in your constructor, you need to initialize that property to
ArrayCollection. The generator took care of that for us.
At the bottom, instead of a getter & setter, we have a getter, adder & remover. There's no special reason for that: the adder & remover methods are just convenient.
Tag. The code here is almost identical: a ManyToMany pointing back
Article and, at the bottom, getter, adder & remover methods.
Great! But, which side is the owning side and which is the inverse side of the
Comment. Remember, with a ManyToOne / OneToMany relationship,
the ManyToOne side is always the owning side of the relation. That's easy to remember,
because this is where the column lives in the database: the
comment table has
But, with a ManyToMany relationship, well, both sides are ManyToMany! In
Tag, the same! So, which side is the owning side?
The answer lives in
Article. See that
inversedby="articles" config? That points
articles property in
Tag. On the other side, we have
which points back to
Phew! Here's the point: with a ManyToMany relationship, you choose the owning
side by where the
mappedBy config lives. The
holds the owning side because that's the entity we chose to update with
Remember, all of this owning versus inverse stuff is important because, when Doctrine
saves an entity, it only looks at the owning side of the relationship to figure
out what to do in the database. So, we can add tags to an article, Doctrine will
save that correctly. But, if you added articles to a tag and save, Doctrine would
do nothing. Well, in practice, if you use
make:entity, that's not true. Why?
Because the generated code synchronizes the owning side. If you call
$tag->addArticle(), inside, that calls
Enough about that! Let's generate the migration:
php bin/console make:migration
Cool! Go open that file. Woh! It creates a new table! Of course! That's how you
model a ManyToMany relationship in a relational database. It creates an
table with only two fields:
This is very different than anything we've seen so far with Doctrine. This is the first time - and really, the only time - that you will have a table in the database, that has no direct entity class. This table is created magically by Doctrine to help us relate tags and articles. And, as we'll see next, Doctrine will also automatically insert and delete records from this table as we add and remove tags from an article.
Run this migration:
php bin/console doctrine:migrations:migrate
Now, let's tag some articles!