AmberLEX
@AmberLEX
php/web-developer

Как получить опубликованные посты по тегу с активной категорией и пользователем?

Учусь.
Есть Entities: User, Category, Post, Tag
Post     - Tag  - many-to-many (таблица post_tag)
Category - Post - one-to-many
User     - Post - one-to-many

Нужно выбрать все Posts по тегу, например "php" (select ... from ... where tags.slug='php') и получить постоы по этому тегу.

В итоге нужно вывести список найденных постов, категорию каждого поста, пользователя и теги каждого поста.

Получается мне нужно на SQL Query Builder написать запрос и выбирать из 4 таблиц с джоинами и условиями?

class PostRepository extends ServiceEntityRepository
{
  public function findAllActiveByTag(string $slug)
  {
    return $this->createQueryBuilder('p')
            ->join('p.tags', 't')->addSelect('t')
            ->leftJoin('p.user', 'u')->addSelect('u')
            ->leftJoin('p.category', 'c')->addSelect('c')
            ->where('t.slug = :slug')->setParameter('slug', $slug)
            ->andWhere('p.isActive = true')
            ->andWhere('c.isActive = true')
            ->orderBy('p.createdAt', 'DESC')
            ->getQuery()
            ->getResult();
}

В шаблоне вывожу примерно так

{{ post.title }}
{{ post.category.name }}
{{ post.user.username }}
{% for tag in post.tags %}
    {{ tag.name }}
{% endfor %}


Но:
- он выбирает все поля из всех таблиц (мне кажется это многовато)
- при выводе списка постов присутствует только тег по которому искал (остальные теги поста отсутствуют)

Вообще правильно ли я делаю?
Как указать только необходимые поля для выборки? (например для юзера только username нужен). Я так понимаю `partial u.{id,username}` не рекомендуют и Creating Partial Objects through DQL is deprecated...
Не очень понятно как вывести все теги к каждому найденному посту?
  • Вопрос задан
  • 94 просмотра
Пригласить эксперта
Ответы на вопрос 1
AmberLEX
@AmberLEX Автор вопроса
php/web-developer
Не знаю насколько это правильно или красиво, решил вопрос так:

class PostRepository extends ServiceEntityRepository
{
    public function findAllActiveByTag(string $slug)
    {
        $ids = $this->createQueryBuilder('p')
            ->select('p.id')
            ->leftJoin('p.tags', 't')
            ->where('t.slug = :slug')
            ->setParameter('slug', $slug)
            ->getQuery()
            ->getSingleColumnResult();

        if ($ids) {
            return $this->createQueryBuilder('p')
                ->leftJoin('p.category', 'c')->addSelect('c')
                ->leftJoin('p.tags', 't')->addSelect('t')
                ->leftJoin('p.user', 'u')->addSelect('u')
                ->where((new Expr())->in('p.id', $ids))
                ->andWhere('p.isActive = true')
                ->andWhere('c.isActive = true')
                ->orderBy('p.createdAt', 'DESC')
                ->getQuery()
                ->getResult();
        } else {
            return [];
        }
    }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы