doctrine queryBuilder where IN collection
Asked Answered
Q

3

6

On my entity I have an array collection of users

/**
 * @ORM\ManyToMany(targetEntity="\UserBundle\Entity\User", mappedBy="acr_groups")
 */
protected $users;

public function __construct() {
    $this->users = new \Doctrine\Common\Collections\ArrayCollection();
}

In my FormType I want to filter out those groups wherein current user is a member:

    $builder
    ->add('acr_group', EntityType::class, array(
        'label' => 'ATS',
        'class' => 'HazardlogBundle:ACRGroup',
        'query_builder' => function (EntityRepository $er) use ($user) { // 3. use the user variable in the querybilder
                $qb = $er->createQueryBuilder('g');
                $qb->where(':user IN (g.users)');
                $qb->setParameters( array('user' => $user) );
                $qb->orderBy('g.name', 'ASC');
                return $qb;
        },
        'choice_label' => 'name'
    ))

My problem is obviously on this line:

$qb->where(':user IN (g.users)');

How can I use my collection of users as the argument for the IN()?

Quindecennial answered 9/11, 2016 at 7:42 Comment(1)
Hello! Can u try to use in expression like this: $qb->where($qb->expr()->in('g.users', $user));Federico
Q
0

I ended up turning thing around a bit after unsuccessfully attempting some of your solutions. I manually created an array of the IDs I wanted.

There is probably a native way of doing this, seems like a pretty standard thing... this works however.

// 1. to inject user entity into this builder first make a construct function (remember to inject it from controller!)

function __construct($user)
{
    $this->user = $user;
}

/**
 * {@inheritdoc}
 */


public function buildForm(FormBuilderInterface $builder, array $options)
{
    $user = $this->user; // 2. instantiate the variable we created in our construct above

    //create group list array
    $groupList = $this->user->getACRGroups();
    $gla = array(); 
    foreach ($groupList as $g) {
        $gla[] = $g->getId();
    };

    $builder
    ->add('acr_group', EntityType::class, array(
        'label' => 'ATS',
        'class' => 'HazardlogBundle:ACRGroup',
        'query_builder' => function (EntityRepository $er) use ($gla) { // 3. use the user variable in the querybilder
                $qb = $er->createQueryBuilder('g');
                $qb->where('g.id IN (:gla)');
                $qb->setParameters( array('gla' => $gla) );
                $qb->orderBy('g.name', 'ASC');
                return $qb;
        },
        'choice_label' => 'name'
    ))
Quindecennial answered 9/11, 2016 at 10:1 Comment(0)
K
3

Try below code

$user = array(12,211,612,84,63,23); // Assuming User Ids whose groups you want to retrive

$builder
->add('acr_group', EntityType::class, array(
    'label' => 'ATS',
    'class' => 'HazardlogBundle:ACRGroup',
    'query_builder' => function (EntityRepository $er) use ($user) { 
            $qb = $er->createQueryBuilder('g');
            $qb->innerJoin('g.users', 'u'); // Inner Join with users
            $qb->where('u.id IN (:user)');
            $qb->setParameters( array('user' => $user) );
            $qb->orderBy('g.name', 'ASC');
            return $qb;
    },
    'choice_label' => 'name'
))

I have tried it in symfony 2.3 with doctrine2. You can use select function with createQueryBuilder() to get specific columns.

Kavita answered 9/11, 2016 at 9:28 Comment(0)
M
0
$q = $this->createQueryBuilder('v')
    ->select('v')
    ->andWhere('v.workingHours IN (:workingHours)')
    ->setParameter('workingHours', $workingHours);

From : Doctrine 2 WHERE IN clause using a collection of entities

Or according to doctrine documentation : http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/query-builder.html#the-expr-class To insert IN condition in query builder with doctrine you can use expr()

$qb->add('select', new Expr\Select(array('u')))
   ->add('from', new Expr\From('User', 'u'))
   ->add('where', $qb->expr()->orX(
       $qb->expr()->eq('u.id', '?1'),
       $qb->expr()->like('u.nickname', '?2')
   ))
   ->add('orderBy', new Expr\OrderBy('u.name', 'ASC'));

Syntaxe of IN :

$qb->expr()->in('u.id', array(1, 2, 3))

Also, Make sure that you do NOT use something similar to $qb->expr()->in('value', array('stringvalue')) as this will cause Doctrine to throw an Exception. Instead, use $qb->expr()->in('value', array('?1')) and bind your parameter to ?1

Magel answered 9/11, 2016 at 8:7 Comment(0)
Q
0

I ended up turning thing around a bit after unsuccessfully attempting some of your solutions. I manually created an array of the IDs I wanted.

There is probably a native way of doing this, seems like a pretty standard thing... this works however.

// 1. to inject user entity into this builder first make a construct function (remember to inject it from controller!)

function __construct($user)
{
    $this->user = $user;
}

/**
 * {@inheritdoc}
 */


public function buildForm(FormBuilderInterface $builder, array $options)
{
    $user = $this->user; // 2. instantiate the variable we created in our construct above

    //create group list array
    $groupList = $this->user->getACRGroups();
    $gla = array(); 
    foreach ($groupList as $g) {
        $gla[] = $g->getId();
    };

    $builder
    ->add('acr_group', EntityType::class, array(
        'label' => 'ATS',
        'class' => 'HazardlogBundle:ACRGroup',
        'query_builder' => function (EntityRepository $er) use ($gla) { // 3. use the user variable in the querybilder
                $qb = $er->createQueryBuilder('g');
                $qb->where('g.id IN (:gla)');
                $qb->setParameters( array('gla' => $gla) );
                $qb->orderBy('g.name', 'ASC');
                return $qb;
        },
        'choice_label' => 'name'
    ))
Quindecennial answered 9/11, 2016 at 10:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.