2012-04-14 3 views
5

У меня есть мои два класса User и Role, и мне нужно сделать QueryBuilder, который возвращает запрос для пользователей, которые имеют ROLE_PROVIDER роль. Мне это нужно для поля формы объекта в Symfony 2. В определении класса формы У меня есть следующий фрагмент кода для указанного поля:Doctrine 2 в Symfony 2 - Фильтрация QueryBuilder ассоциацией

$builder->add('provider', 'entity', array(
    'class' => 'ElCuadreAccountBundle:User', 
    'property' => 'username', 
    'query_builder' => function(UserRepository $ur) { 
         return $ur->getUsersByRoleQB('ROLE_PROVIDER'); 
         }, 
    'required' => true, 
)); 

И тогда в моем Настраиваемом UserRepository У меня есть следующая функция, которая должна возвращать QueryBuilder объект:

public function getUsersByRoleQB($role) { 
    $qb = $this->createQueryBuilder('u'); 
    return $qb->join('u.roles','r') 
       ->where($qb->expr()->in('r.role',$qb->expr()->literal($role))) 
       ->orderBy('u.username', 'ASC'); 
} 

конечно, это не работает, но я вставил его, чтобы проиллюстрировать мои потребности.

Я оглядывался, и кажется, что Doctrine2 не поддерживает естественную фильтрацию по ассоциации. В this page они так говорят и предлагают использовать DQL для такого рода фильтрации. Моя проблема в том, что я не нашел, как сделать объект QueryBuilder из предложения DQL. Если бы вы могли также предоставить мне правильный запрос DQL, я был бы очень признателен ...

Спасибо за вашу помощь!

ответ

11

где должно фактически делать то, что вы хотите. Вы просто синтаксис неправильно для «в»:

Это

->where($qb->expr()->in('r.role',$qb->expr()->literal($role))) 

Должно быть

->where($qb->expr()->in('r.role',$role)) 

Я знаю, это может показаться немного странным, но так как подготовленные заявления непосредственно не поддерживают массивы, параметры к предложениям IN всегда должны быть экранированы индивидуально (какая доктрина делает для вас). Следовательно, синтаксис немного отличается, а затем выражается выражение eq, где требуется литерал.

Вы поднимаете хороший вопрос, потому что мне нужно фильтровать по ассоциации. Я думаю, D2.2 позволит это из коробки. Я на самом деле не пробовал, но я подозреваю, что

$dql = 'a,b FROM whatever...'; // Don't start with SELECT 
$qb->select($dql); 
return $qb; 

действительно будет работать без указания каких-либо других частей до тех пор, как ваш отпуск фактического «SELECT» строка из $ DQL. Непроверенные.

+0

Спасибо! действительно полный ответ ... Один вопрос, это не очень связано с оригинальным вопросом, но здесь я иду ... Я несколько раз читал, что появляются новые версии symfony 2 и doctrine 2, и люди, кажется, знают новые функции, но я устал от запуска 'php bin/vendors install', и он не обновляет ни symfony, ни доктрину ... как я могу обновить? или когда эти новые версии станут официальными? спасибо за Ваш ответ!!! – Throoze

+0

Вы можете прочитать о D2.2 здесь: http://www.doctrine-project.org/. S2 не будет интегрирован D2.2 до тех пор, пока S2.1 не будет выпущен, вероятно, этим летом. Однако вы можете установить D2.2 напрямую, настроить свои пути в autoload.php и, по большей части, ваш код доктрины должен работать. Проверьте документы для вещей, о которых нужно помнить. – Cerad

+0

Спасибо за ответы! – Throoze

3

даже еще проще вы можете сделать:

->where('r.role IN (:role)') 
->setParameter('role', $role); 

Я нахожу это гораздо более разборчивыми, чем добавив $ qb-> выражение() ...