I'm trying to get Posts by Tags in Symfony 4 with Doctrine. I have three tables like this:
Post
------------------------------
| id | title | content | ... |
------------------------------
Tag
-------------
| id | name |
-------------
TagPost (which makes the association between tags and posts)
--------------------
| tag_id | post_id |
--------------------
There can be several tags by posts and a tag can be used for several posts, that's why I use an association table.
I already succeeded to get it but only with raw sql, I have tried multiple times with the query builder and no way to get it. Any advices ?
The query (working):
"SELECT post.id, post.title, post.author_id, post.content, post.datetime,
post.tile FROM post
INNER JOIN tag_post ON post.id = tag_post.post_id
INNER JOIN tag ON tag_post.tag_id = tag.id
WHERE tag.id = " . $tag_id;
Assuming you're writing this inside a method in your PostRepository (https://symfony.com/doc/3.3/doctrine/repository.html), you'd write:
$qb = $this->createQueryBuilder('post')
->select('post.id, post.title, post.author_id, post.content, post.datetime, post.tile')
->innerJoin('post.tag', 't')
->where('t.id = :tagid')
->setParameter('tagid', $tag_id)
;
$result = $qb->getQuery()->getResult();
Several things to note:
createQueryBuilder
method is not exactly the same in a Repository and in an EntityManager. The EntityManager one needs a ->from()
method, while the Repository one guesses the 'from' table and takes instead just a constructor argument for the alias.->innerJoin
method will only need one additional parameter: the alias. If you could include your entities definitions, that would help troubleshoot any additional problems.post.tile
(at the end of the SELECT clause) on purpose or is it a misspelling of post.title
?