-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Remove unused tag #474
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
Remove unused tag #474
Conversation
src/AppBundle/Entity/Tag.php
Outdated
| * @var array | ||
| * | ||
| * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Post", mappedBy="tags") | ||
| */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stof: we don't need it. You never use it (and it does not really make sense to have it anyway as tags don't need to be aware of posts). #192 (diff)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @yceruto. There is a Doctrine best practice:
Avoid bidirectional relationships.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I put this relation to make the query in the TagRepository
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Grafikart, you can delete unused tags using just one SQL query.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and even in DQL, you don't need to have a relation to be able to do a join
| if ($form->isSubmitted() && $form->isValid()) { | ||
| $post->setSlug($this->get('slugger')->slugify($post->getTitle())); | ||
| $entityManager->flush(); | ||
| $this->getDoctrine()->getRepository(Tag::class)->cleanUnusedTags(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it necessary to do this? the unused tags could be used for new posts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personal choice mainly (I understand if you close the issue).
Having tags attached to nothing could create some problem if you choose to create a tagcloud later for instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as you do it using a separate query, you should wrap the flush and this query in a transaction, to be atomic.
src/AppBundle/Entity/Tag.php
Outdated
| * | ||
| * @return Tag | ||
| */ | ||
| public function addPost(\AppBundle\Entity\Post $post) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this adder is worse than anything else you did, because it will not add the post (as you don't update the owning side of the relation)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing everything from this entity sorry
| use AppBundle\Entity\Tag; | ||
| use Doctrine\ORM\EntityRepository; | ||
| use Doctrine\ORM\Query; | ||
| use Pagerfanta\Adapter\DoctrineORMAdapter; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why pagerfanta ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo sorry
| * See http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes | ||
| * | ||
| * @author Ryan Weaver <[email protected]> | ||
| * @author Javier Eguiluz <[email protected]> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
authors look wrong here
| if ($form->isSubmitted() && $form->isValid()) { | ||
| $post->setSlug($this->get('slugger')->slugify($post->getTitle())); | ||
| $entityManager->flush(); | ||
| $this->getDoctrine()->getRepository(Tag::class)->cleanUnusedTags(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could make this code much more efficient, by getting the old list of tags of the Post in an array before handleRequest, then comparing it to the list of new tags here. The difference will give you the list of tags removed from the post, which are the only ones you need to check for being unused
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, but it would add more code to the controller, is it acceptable ?
|
I can't figure how to do this query using DQL https://github.com/symfony/symfony-demo/pull/474/files#diff-2629962eca7be81a3484a3f64ad18074R36 (can't find a way to do a join on the join table without having a ManyToMany between Tag and Post owned by Tag) |
| if ($form->isSubmitted() && $form->isValid()) { | ||
| $post->setSlug($this->get('slugger')->slugify($post->getTitle())); | ||
| $entityManager->flush(); | ||
| $entityManager->transactional(function ($entityManager) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate your contribution ... but using $entityManager->transactional is "light years" ahead of what we want to teach in the Symfony Demo app. I'm sorry but we can't use this obscure feature. We'll need to find a much simpler alternative solution. Thanks for understanding it.
| $joinTable = $this->getEntityManager()->getClassMetadata(Post::class)->getAssociationMapping('tags')['joinTable']['name']; | ||
| $tagTable = $this->getClassMetadata()->getTableName(); | ||
| $unused_tags = $this->getEntityManager()->createNativeQuery(" | ||
| DELETE FROM `$tagTable` WHERE id IN |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Grafikart , try to use:
DELETE FROM tags t
LEFT JOIN tags_posts j ON j.tag_id = t.id
WHERE j.tag_id IS NULL
When a tag is detached from a post it stays in the Tag table filling the table over time. When we update (or delete a post) we clean up unused (unlinked tags)
Improvments ideas 💡