С официального сайта:
// src/AppBundle/Entity/Category.php
// ...
use Doctrine\Common\Collections\ArrayCollection;
class Category
{
// ...
/**
* @ORM\OneToMany(targetEntity="Product", mappedBy="category")
*/
protected $products;
public function __construct()
{
$this->products = new ArrayCollection();
}
}
// src/AppBundle/Entity/Product.php
// ...
class Product
{
// ...
/**
* @ORM\ManyToOne(targetEntity="Category", inversedBy="products")
* @ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
protected $category;
}
База данных:
Category:
id | name
1 | main
2 | test
3 | it
Product:
id | category_id | name | created_at
1 | 1 | aaa | 2014-10-10
2 | 1 | bbb | 2014-11-10
3 | 2 | vvv | 2014-09-14
4 | 1 | ddd | 2014-12-12
5 | 3 | ccc | 2014-11-11
6 | 2 | fsd | 2014-11-14
7 | 3 | fff | 2014-09-23
и т.д
Теперь я хотел бы получить все продукты, где created_at> 2014-10-01, так:
$repository = $this->getDoctrine()
->getRepository('AppBundle:Category');
$query = $repository->createQueryBuilder('c');
$query->leftJoin('c.products', 'p')
->andWhere('p.created_at > :date')
->setParameter('date', '2014-10-01');
$categories = $query->getQuery()->getResult();
И показать в Twig:
{% for category in categories %}
<h1>{{ category.name }}</h1>
{% for product in category.products %}
<h2>{{ product.name }}</h2>
{% endfor %}
{% endfor %}
Это не возвращает никаких ошибок, но условие, в котором они не работают. Это показывает мои все продукты, но я бы хотел получить только продукты с датой> 2014-10-01.
Когда вы создаете запрос, этот поиск по категориям, он фильтрует объекты категории со всеми агрегированными объектами. where
используется для фильтрации категорий, а не продуктов здесь. Если вы хотите фильтровать продукты, вы должны использовать ProductRepository для создания построителя запросов.
Некоторый код:
$repository = $this->getDoctrine()
->getRepository('AppBundle:Product');
$query = $repository->createQueryBuilder('p');
->select('p, c')
->leftJoin('p.category', 'c')
->andWhere('p.created_at > :date')
->setParameter('date', '2014-10-01');
$products = $query->getQuery()->getResult();
$res = array_reduce($products, function($r, $product) {
$cid = $product->getCategory()->getId();
isset($r[$cid]) || $r[$cid] = ['category'=> $product->getCategory(), 'products' => []];
$r[$cid]['products'][] = $product;
return $r;
}, []);
А потом в веточке
{% for r in res %}
<h1>{{ r.category.name }}</h1>
{% for product in r.products %}
<h2>{{ product.name }}</h2>
{% endfor %}
{% endfor %}
Если вы хотите получить продукты, сделайте это в Productrepository, а не в категории.
$entityManager = $this->getDoctrine()->getManager();
$queryBuilder = $entityManager->createQueryBuilder();
$query = $queryBuilder
->select(array('p'))
->from('AppBundle:Product', 'p')
->leftJoin('p.category', 'c')
->where($queryBuilder->expr()->gt('p.created_at', ':date'))
->setParameter('date', '2014-10-01')
;
$products = query->getQuery()->getResult();
И передать его Твиг.