Symfony2 эффективно отображает список категорий и сопутствующих товаров - PullRequest
2 голосов
/ 01 декабря 2011

У меня есть отношение Category и Product (один ко многим).Я хочу отобразить список всех категорий и объектов, связанных с ними.Если я использую:

$categories = $this->getDoctrine()->getRepository('AcmeZebraBundle:Category')->findAll();

И затем отобразить это так:

<ul>
{% for category in categories %}
    <li>{{ category.name }}</li>
    <ul>
    {% for product in category.products %}
    <li>{{ product.name }}</li>
    {% endfor %}
    </ul>
{% endfor %}
</ul>

Будет сгенерирован дополнительный запрос для каждой категории.Я пытался добавить товары в категории - вместо findAll() я использовал метод, который извлекает все объекты и добавляет их в ArrayCollection соответствующей категории.Но это не уменьшает количество запросов.

public function findAllLoadProducts()
{
    $categories = $this->findAll();
    $categortiesById = array();

    foreach ($categories  as $category)
    {
        $categortiesById[$category->getId()] = $category;
    }

    $products = $this->getEntityManager()->getRepository('AcmeZebraBundle:Product')->findAll();

    foreach ($products as $product)
    {
        $categortiesById[$product->getCategory()->getId()]->getProducts()->add($product);
    }

    return $categortiesById;
}

1 Ответ

1 голос
/ 01 декабря 2011

Вам необходимо упорядочить продукты по категориям в пользовательском запросе.Создайте репозиторий для вашей сущности Category в том же пакете (или используйте его, если вы его уже создали):

<?php
/* src/Acme/ZebraBundle/Repository/CategoryRepository.php */
namespace Acme\ZebraBundle\Repository;

use Doctrine\ORM\EntityRepository;

class CategoryRepository extends EntityRepository
{
    public function retrieveHydratedCategories()
    {
        return $this->createQueryBuilder('c')
                    ->select('c, p')
                    ->leftJoin('c.products', 'p')
                    ->getQuery()
                    ->execute();
    }
}

Затем вы можете использовать этот запрос вместо вашего предыдущего "findall":

$categories = $this->getDoctrine()->getRepository('AcmeZebraBundle:Category')->retrieveHydratedCategories();

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...