P
P
Pavel Novikov2018-05-29 11:15:37
MySQL
Pavel Novikov, 2018-05-29 11:15:37

How to get unique value of fields in Symfony EntityType?

I have a form built with Symphony's Form Component. There is a table that stores certain localizations and cities in which these localizations are located, and there can be several localizations in one city, for example:

  1. Moscow - localization 1
  2. Moscow - localization 2
  3. SPb - localization 3

To build the city selector I use EntityType and the field looks like this:
$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,
            ])

The problem is that the query in the query_builder parameter returns me all the values ​​of cities from the database, that is, Moscow is repeated 2 times in the select.
The question is how to make the EntityType choose distinct values ​​for me in the form, that is, without duplicates

Answer the question

In order to leave comments, you need to log in

3 answer(s)
D
Denis Derepko, 2018-05-29
@uDenX

Use grouping by city?

V
voronkovich, 2018-05-30
@voronkovich

Generally speaking, you'd be better off normalizing the location table and moving the cities into a separate City entity.
The DISTINCT statement applies to the entire dataset and would not work in your case. Yes, and there is no analogue in QueryBuilder. See https://www.doctrine-project.org/api/dbal/2.6/Doct...
It will be correct as Denis Derepko advises above , i.e. use QueryBuilder#groupBy :

$repository
    ->createQueryBuilder('l')
    ->orderBy('l.addressCity', 'ASC')
    ->groupBy('l.addressCity');

P
Pavel Novikov, 2018-05-30
@paulfcdd

I solved the problem as follows:
1) I defined the form as a service and passed EntityManagerInterface as an argument
2) I used ChoiceType instead of EntityType and put the request into a separate method
As a result, it turned out like this

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

And the `getCitiesArray` method
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;
    }

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question