Как я могу использовать QueryBuilder с FormBuilder в Symfony 4?

#php #symfony #oop #query-builder #formbuilder

#php #symfony #ооп #конструктор запросов #formbuilder

Вопрос:

У меня возникают трудности с использованием конструктора запросов в Symfony. Таким образом, в моем окне выбора перечислены все данные, которые хранятся в моей сущности «Параметры»:

 $options['class'] = Options::class;
$options['choice_label'] = function ($value) {
    return $value->getName();
};

$formBuilder->add($name, $class, $options);
  

Но я хочу отфильтровать данные, чтобы параметры отображали только те данные, которые связаны с определенным идентификатором моей сущности «Поля».

Это мой подход с query Builder:

 $options['class'] = Options::class;
$options['choice_label'] = 'id';
$options['query_builder'] = function (EntityRepository $id) {
    return $this->createQueryBuilder('f')
        ->leftJoin('f.fields', 'fi')
        ->where(":id MEMBER OF f.fields")
        ->setParameter(':id', $id)
        ->getQuery()
        ->execute();
};
  

Сообщение об ошибке, которое я получаю, является:

Аргумент 1, передаваемый в App Controller PagesController::App Controller{closure}() должен быть экземпляром App Controller EntityRepository, заданным экземпляром App Repository OptionsRepository, вызываемым в /Users/work/project/vendor/symfony/doctrine-bridge/Form/Type/EntityType.php в строке 32

Комментарии:

1. Изменить typehint?

2. Вы импортировали EntityRepository в класс, содержащий эту форму?

Ответ №1:

Давайте начнем с того факта, что EntityRepository это репозиторий core Doctrine, который находится в DoctrineORMEntityRepository; пространстве имен. Я также сомневаюсь, что у вас есть другой EntityRepository в вашем проекте.

Итак, первая ошибка заключается в неправильной подсказке типа. Вы должны добавить use DoctrineORMEntityRepository; перед вашим контроллером. OptionsRepository будет соответствовать этому определению по мере его расширения EntityRepository или, по крайней мере, должно соответствовать.

Вторая ошибка ->setParameter(':id', $id) — вы не можете установить репозиторий в качестве параметра запроса, это бесполезно. Я не знаю, что это такое, $id но, как и в случае с любыми другими функциями обратного вызова, вы можете use это.

И в-третьих, как называется опция query_builder — ваш обратный вызов должен вернуть QueryBuilder , поэтому удалите ->getQuery()->execute(); .

В конце правильный код должен быть:

 use DoctrineORMEntityRepository;

//....

$options['query_builder'] = function (EntityRepository $er) use ($id) {
    return $er->createQueryBuilder('f')
        ->leftJoin('f.fields', 'fi')
        ->where(":id MEMBER OF f.fields")
        ->setParameter(':id', $id);
};
  

Комментарии:

1. Спасибо, это мне очень помогает в неразберихе. Я сделал то, что вы предложили. У меня все еще есть ошибка Expected argument of type "DoctrineORMQueryBuilder", "array" given Я должен выяснить, как ее решить, и сообщить вам, как только у меня будет решение

2. Мне пришлось удалить последние две строки ->getQuery() ->execute(); , и тогда это сработало!

Ответ №2:

Также убедитесь, что у вашего объекта правильно установлен repositoryClass, если вы вводите весь репозиторий.

Сущность

 /**
 * Category.
 *
 * @ORMTable(name="category")
 * @ORMEntity(repositoryClass="AppRepositoryCategoryRepository")
 */
class Category
{
...
}
    
  

Затем

 $builder->add('categories', EntityType::class, [
    'class' => Category::class,
    'query_builder' => function (CategoryRepository $categoryRepository) {
        return $categoryRepository->getQueryBuilderForProductCreation();
     },
    'choice_label' => 'name',
]);