-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
2019/06/11/doctrine-inheritance #4
Comments
There is also another useful tool in the Doctrine’s toolbox: embeddables. They are really really powerful and are a perfect fit for things like pictures or videos like in your example: they are basically value objects and embeddables make use and persistence of value objects really a piece of cake! |
Yes, they are a great and underused Doctrine feature! Indeed they would make sense for my first example. They would be my first option when you have a value object, and traits being best when you want to add just a few properties without meaning on their own (ie, adding "createdAt" and "updatedAt" fields...). |
Exactly: this is exactly the way I use both of them! :) |
Thank you, I appreciate :) |
Oh, great! Maybe you will find interesting the post I wrote about value objects: https://io.serendipityhq.com/experience/php-and-doctrine-immutable-objects-value-objects-and-embeddables/ I also wrote a small library around the most common value objects from which you may find inspiration: https://github.com/Aerendir/PHPValueObjects |
I still don't understand how the database and entities would look like in a polymorphic many to many relationship, say: class Tag {}
class PostTag extends Tag {}
class VideoTag extends Tag {}
class Post {}
class Video{} What i would like to have is a many-to-many relationsihp between Laravel's Eloquent works with a pivot with |
@marcosdipaolo , exactly the same. You will have a table About single inheritance, are you speaking about a tree of tags? It is possible through a self referencing relationship: |
Yes, sorry, i forgot to write the |
@marcosdipaolo I'm not sure to correctly get your scenario. First of all, are |
Thanks for that great post. Besides doing a great job explaining the different types (better than Doctrine's documentation, IMHO, too), your final word of maybe just using traits really simplified my project and my thought process! |
@romaricdrigon forget about the example, what i need is a manyToMany polymorphic relationship where an entity can have manyToMany relationships with more than one entity trying to avoid having multiple pivot tables. I just don't understand how you achieve that with doctrine.
|
@marcosdipaolo that is what I am looking for as well.... |
@marcosdipaolo you will be hitting one of the limitations of Doctrine inheritance: Doctrine can not handle polymorphic relationships (as far I know. In database). In the database, the The best solution I can think of would be to have nullable fields, as such:
PHP-side, you can have a |
thanks for your answer @romaricdrigon
I just have to create a 'two columns' index between Of course there isn't a queryBuilder method for that, something like this is necesary (I made the type a ValueObject): public function getByEntityAndType(Taggable $entity, TaggableType $type)
{
$qb = $this->createQueryBuilder('cc');
$expr = $qb->expr();
$qb->where($expr->andX(
$expr->eq('taggableType.type', ':type'),
$expr->eq('taggableId', ':id')
));
$qb->setParameter('type', $type->getType());
$qb->setParameter('id', $entity->getId());
return $qb->getQuery()->getResult();
} |
@marcosdipaolo if I am not misteaken you cannot use those querybuilder calls inside a Entity. So for example how do you handle inside the Video entity a getTags() call to retrieve an ArrayCollection? |
hi @parijke |
Do you have a visible repo where you used this technique? I need something like this for attachments to all kind of entities |
Can you explain further on
|
In that specific case, using CTI or STI the biggest drawback that I can think of is what if you want to have 2 pictures or videos? For both STI and CTI, you'd have another nullable column in the database, or you'd have to create a Instead, using composition, an article can have zero or more pictures and zero or more videos. If you have a need for a version where a certain number of pictures and/or videos are required, you can handle that in your validation logic before persistence, but it really doesn't (always) need to be represented in the entity itself, nor does the database need to be aware of that. There are definitely times when this isn't the case, and the author notes that they have seen one valid example, but it is pretty rare. (I'm saying all of this having built a full CTI system with infinite hierarchy, where every entity was based on a shared "root object", and every object also supported a "parent object". Describing the restrictions on what could or could not participate in the parent/child relationship was part of the nightmare and required insanely complicated SQL with hard-coded magic strings, and, CTEs were all but impossible. It was great when I built it, but 6 months later it was a nightmare to make the smallest changes. After a couple of years I finally migrated back to dedicated entities with composition and the code is so much easier to reason about. |
@vuvgaG-dukgu3-wysnox just to rephrase, the better option would have been one Article entity with a one-to-many relationship to Picture entities ; and a one-to-many relationship to Video entities. cjhaas described quite well details and technical advantages. I would add that the first and foremost reasoning for me, when doing software architecture, is always around vocabulary, around the semantic. I try to see if concepts are semantically different, and if so, inheritance (Doctrine or not) is a no go. @cjhaas thank you for the story, in italics, it is always nice to read other people experiences. Though of course I could wish you nicer and more successful experiences :) |
Great article Using traits can work very well, and I have been using them (https://github.com/siganushka/generic-bundle), but traits are not perfect, such as constructors, and the order of attributes cannot be controlled. |
Hey, thanks a lot for this exciting article. |
Please comment below! Comments will automatically be published on the blog, too.
The text was updated successfully, but these errors were encountered: