Лучший способ получить все дочерние таксоны корневого таксона

Я пытаюсь создать динамическое меню на основе таксонов из корневого таксона «Категория». Это меню, которое я хочу получить:

  • Taxon A
    • Taxon A1
    • Таксон А2
  • Taxon B
    • Taxon B1
      • Taxon B1a
      • Таксон B1b

Я закодировал что-то, что работало следующим образом:

Во-первых, я переопределил репозиторий таксонов

use Sylius\Bundle\...\TaxonRepository as BaseRepository;

class TaxonRepository extends BaseRepository
{
    /**
     * @return \Doctrine\Common\Collections\ArrayCollection
     */
    public function findForMenu()
    {
        return $this
            ->createQueryBuilder('t')
            ->innerJoin('t.taxonomy', 'ta')
            ->innerJoin('ta.root', 'r')
            ->where('ta.name = :name')
            ->andWhere('t.parent = r')
            ->setParameter('name', 'Category')
            ->getQuery()
            ->getResult();
    }
}

Затем я создал конструктор меню.

class MenuBuilder
{
    private $factory;
    private $repository;

    public function __construct($factory, TaxonRepository $repository)
    {
        $this->factory = $factory;
        $this->repository = $repository;
    }

    public function createMain(Request $request)
    {
        $menu = $this->factory->createItem('root');

        foreach ($this->repository->findForMenu() as $taxon) {
            $menu->addChild($this->buildChild($taxon));
        }

        return $menu;
    }

    private function buildChild(Taxon $taxon)
    {
        $item = $this->factory->createItem($taxon->getName());

        foreach ($taxon->getChildren() as $child) {
            $item->addChild($this->buildChild($child));
        }

        return $item;
    }
}

Это работало хорошо, но из-за ленивой загрузки было много запросов, поэтому я решил использовать поведение ClosureTreeRepository (от Gedmo). Я понял, что не могу этого сделать, так как вы должны наследовать репозиторий Sylius и не можете наследовать репозиторий ClosureTreeRepository Gedmo.

Любые подсказки о том, как правильно построить дерево таксонов с помощью ORM?


person Geoffrey Brier    schedule 21.01.2015    source источник


Ответы (1)


Вы получаете много запросов из-за ленивой загрузки. Чтобы предотвратить это, вы должны обновить свой запрос, добавив ->select() и выбрать все, что вам нужно, чтобы построить меню.

Что-то вроде этого:

class TaxonRepository extends BaseRepository
{
    public function findForMenu()
    {
        return $this
            ->createQueryBuilder('t')
            ->select('t', 'ta', 'r')
            ->innerJoin('t.taxonomy', 'ta')
            ->innerJoin('ta.root', 'r')
            ->where('ta.name = :name')
            ->andWhere('t.parent = r')
            ->setParameter('name', 'Category')
            ->getQuery()
            ->getResult();
    }
}
person umpirsky    schedule 22.01.2015