简体   繁体   中英

Use where in relations

From official site:

// 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;
}

Database:

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

etc

Now I would like get all products where created_at > 2014-10-01, so:

$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();

And show in Twig:

{% for category in categories %}
  <h1>{{ category.name }}</h1>
  {% for product in category.products %}
     <h2>{{ product.name }}</h2>
  {% endfor %} 
{% endfor %}

This not returns any errors, but clause where not working. This showing my all products, but i would like get only products with date > 2014-10-01.

When you build query, that search for categories, it filter Category objects with all aggregated objects. where clause is used to filter categories, not products here. If you wanna filter Products, you should use ProductRepository to create Query builder.

Some code:

$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;
}, []);

And then in twig

{% for r in res %}
  <h1>{{ r.category.name }}</h1>
  {% for product in r.products %}
    <h2>{{ product.name }}</h2>
  {% endfor %} 
{% endfor %}

If you want to fetch products do it in Productrepository not in Category.

$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();

And pass it to Twig.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM