paulfcdd
@paulfcdd
PHP/Sf/WEB developer

Как получить уникальные значение полей в Symfony EntityType?

У меня есть форма, построенная при помощи Form Component в Симфони. Есть таблица в которой хранятся определенный локализации и города, в которых эти локализации находятся и в одном городе может быть несколько локализаций, например:
  1. Москва - локализация 1
  2. Москва - локализация 2
  3. СПб - локализация 3


Для построения селектора городов я использую EntityType, и поле выглядит следующим образом:
$builder
            ->add('citySelector', EntityType::class, [
                'class' => Location::class,
                'expanded' => false,
                'multiple' => false,
                'query_builder' => function (EntityRepository $repository) {

                    return $repository
                        ->createQueryBuilder('l')
                        ->orderBy('l.addressCity', 'ASC')
                        ->distinct();
                },
                'choice_label' => 'addressCity',
                'attr' => [
                    'class' => 'form-control'
                ],
                'label' => 'warehouse_filter_form.city',
                'placeholder' => 'warehouse_filter_form.any',
                'required' => false,
            ])


Проблема в том, что запрос в параметре query_builder возвращает мне все значения городов из БД, то есть 2 раза в селекте повторяется Москва.
Вопрос заключаетя в том, как в форме заставить EntityType выбирать мне значения distinct, то есть без дубликатов
  • Вопрос задан
  • 442 просмотра
Пригласить эксперта
Ответы на вопрос 3
uDenX
@uDenX
PHP Developer
Использовать группировку по городу?
Ответ написан
voronkovich
@voronkovich
Вообще говоря, вам лучше сделать нормализацию таблицы локаций и вынести города в отдельную сущность City.

Оператор DISTINCT применяется ко всему набору данных, и в вашем случае не сработал бы. Да и его аналога в QueryBuilder нет. См. https://www.doctrine-project.org/api/dbal/2.6/Doct...

Правильно будет так, как выше советует Денис Дерепко, т.е. использовать QueryBuilder#groupBy:

$repository
    ->createQueryBuilder('l')
    ->orderBy('l.addressCity', 'ASC')
    ->groupBy('l.addressCity');
Ответ написан
paulfcdd
@paulfcdd Автор вопроса
PHP/Sf/WEB developer
Я решил проблему следующим образом:
1) Определил форму как сервис и в качетсве аргумента передал EntityManagerInterface
2) вместо EntityType использовал ChoiceType и вынес запрос в отдельный метод

В итоге получилось так
$builder
            ->add('citySelector', ChoiceType::class, [
                'choices' => array_flip($this->getCitiesArray()),
                'expanded' => false,
                'multiple' => false,
                'attr' => [
                    'class' => 'form-control'
                ],
                'label' => 'warehouse_filter_form.city',
                'placeholder' => 'warehouse_filter_form.any',
                'required' => false,
            ])


И метод `getCitiesArray`
private function getCitiesArray()
    {
        $cities = [];

        $results = $this->em->createQueryBuilder()
            ->select('l.addressCity')
            ->from(Location::class, 'l')
            ->groupBy('l.addressCity')
            ->orderBy('l.addressCity', 'ASC')
            ->getQuery()
            ->getArrayResult();

        foreach ($results as $result) {
            if (!in_array($result['addressCity'], $cities)) {
                $cities[$result['addressCity']] = $result['addressCity'];
            }
        }

        return $cities;
    }
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы