Использовать где в отношениях

0

С официального сайта:

// 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.

Теги:
doctrine2

2 ответа

1
Лучший ответ

Когда вы создаете запрос, этот поиск по категориям, он фильтрует объекты категории со всеми агрегированными объектами. 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 %}
  • 0
    Спасибо, но как использовать это в TWIG? Не могли бы вы добавить пример для меня?
  • 0
    Добавил простой пример
1

Если вы хотите получить продукты, сделайте это в 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();

И передать его Твиг.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню