Согласно Учение 2 документа здесь Вы можете создать иерархию сущностей, используя класс с самосвязью «один ко многим». Я хочу иметь возможность запрашивать все категории со всеми связанными детьми.
В этот момент, когда я выгружаю из контроллера запрос возвращает «неинициализированный»: #collection: ArrayCollection -elements: [].
Я не знаю, как настроить QueryBuilder для увлажнения детей.
Код внутри репозитория категорий:
public function retrieveHydratedCategories()
{
return $this->createQueryBuilder('c')
->select('c, p, b')
->leftJoin('c.products', 'p')
->leftJoin('p.brand', 'b')
->Where("c.isActive = 1")
->getQuery()
->execute();
}
Моя категория:
<?php
// src/Entity/Category.php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;/**
* @ORM\Entity(repositoryClass="App\Repository\CategoryRepository")
* @ORM\Table(name="categories")
*/
class Category
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=25)
*/
private $name;
/**
* @ORM\Column(type="string", length=64)
*/
private $brand;
/**
* @ORM\Column(type="string", length=100)
*/
private $image;
/**
* One ProductCategory has Many ProductCategories.
* @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
*/
private $children;
/**
* Many ProductCategories have One ProductCategory.
* @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
*/
private $parent;
/**
* @ORM\Column(name="is_active", type="boolean")
*/
private $isActive;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Product", mappedBy="category")
*/
private $products;
public function __construct()
{
$this->products = new ArrayCollection();
$this->children = new ArrayCollection();
}
/**
* @return Collection|Product[]
*/
public function getProducts()
{
return $this->products;
}
public function getChildren()
{
return $this->children;
}
public function getParent()
{
return $this->parent;
}
public function getName()
{
return $this->name;
}
public function getId()
{
return $this->id;
}
public function getImage()
{
return $this->image;
}
public function setName($name)
{
$this->name = $name;
}
public function addChildren (Category $children)
{
$this->children[] = $children;
return $this;
}
public function setIsActive($isActive)
{
$this->isActive = $isActive;
}
public function getBrand()
{
return $this->brand;
}
}
Самостоятельно ссылающиеся ассоциации «один ко многим» ничем не отличаются от обычных ассоциаций «один ко многим», когда дело доходит до гидратации коллекции. Если вы хотите получить прямых потомков ваших категорий, вам нужно будет добавить еще одно объединение к вашему текущему запросу. Что-то вроде:
public function retrieveHydratedCategories()
{
$qb = $this->createQueryBuilder('c');
// your other joins and conditions ...
$qb->leftJoin('c.children', 'children')->addSelect('children');
return $qb->getQuery()->getResult();
}
При этом, это работает, только если у вас есть один уровень глубины. Если вы хотите получить детей от детей, вам нужно будет либо добавить еще одно соединение (увидеть этот пост) или сгенерируйте свое дерево категорий из простого набора результатов, как обсуждалось Вот.
То же самое относится и к products
объединение детей. Соответствующие коллекции не будут гидратированы, если вы не добавите конкретное объединение в свой запрос, нацеленный на продукты дочерних элементов (ну, возможно, он будет гидратирован, если дочерний элемент также является родителем, полученным в основном наборе результатов …).
Других решений пока нет …