Создайте, если данные не существуют с Symfony 4

У меня есть форма, которую пользователь заполнил именем. Основываясь на этом имени, я делаю AJAX-запрос к своей базе данных, чтобы узнать, существует ли кто-то с таким именем. Если он существует, я показываю полную форму с входными данными, заполненными данными из базы данных. В противном случае я показываю пустую полную форму. При отправке, если данные уже были в базе данных, я хочу их обновить, но если нет, мне нужно вставить эти данные. Вставка новых данных работает нормально.

Вот моя функция контроллера, связанная с отправкой формы:

    /**
     *@Route("adherent/new", name = "adherent_new")
     */
    public function new(Request $request)
    {
        $adherent = new Adherent();
        $em = $this->getDoctrine()->getManager();

        $form = $this->createForm(AdherentType::class, $adherent);    
        $form->handleRequest($request);

        $produitRepository = $em->getRepository(Produit::class);
        $allProduit = $produitRepository->findAll();

        if ($form->isSubmitted() && $form->isValid()){
            $id = $request->request->get('id');
            //if id exists then update
            //otherwise create a new entry

            $adherent = $form->getData();
            $em->persist($adherent);
            $em -> flush();

            return $this->redirectToRoute('adherent_accueil');
        }


        return $this->render('adherent/new.html.twig', [
            'form' => $form->createView(),
            'produits' => $allProduit
        ]);

    }

Есть ли способ справиться с этим с помощью Symfony? Или мне нужно сделать это вручную?

Заранее спасибо !

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
1 732
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вместо создания нового $adherent вы можете загрузить конкретного приверженца из своей базы данных. Вручную, как в документация, но вы можете использовать Автоматическая выборка объектов (ParamConverter), что очень чисто:

composer require sensio/framework-extra-bundle
// src/Controller/ProductController.php
use App\Entity\Product;

/**
 * @Route("/product/{id}", name = "product_show")
 */
public function show(Product $product)
{
    // use the Product!
    // ...
}

Затем, когда вы создадите свою форму с $adherent, которая теперь является объектом с информацией из вашей базы данных: $form = $this->createForm(AdherentType::class, $adherent);

Он автоматически заполнит поля формы соответствующими данными.

Я не профессионал Symfony, но я использовал его там. Посмотрите на маршрут "/terminal/create" и "/terminal/{id}/edit", если я правильно понял, он похож на то, чего вы хотите достичь.

РЕДАКТИРОВАТЬ

Если вы установите идентификатор вашего объекта перед отправкой в ​​​​базу данных, он обновит вашего приверженца, если у него нет идентификатора, он создаст новый. Я думаю, вам просто нужно добавить:

if ($id){
    $adherent->setId($id);
}

РЕДАКТИРОВАТЬ

перечитывая в вашем коде $adherent = $form->getData(); вероятно, уже настроен идентификатор вашего объекта, если идентификатор находится в вашей форме. Это означает, что он уже должен работать так, как вы ожидаете (обновление приверженца, если идентификатор установлен в вашей форме, и создание приверженца, если идентификатор пуст). Если нет, можете ли вы указать код своей сущности и формы?

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

Azeann 11.07.2019 09:08

ок, извините. Я действительно не ответил на вашу проблему тогда. Я постараюсь обновить свой ответ чем-то более точным

Rémi Girard 11.07.2019 12:46
Ответ принят как подходящий

Хорошо, я понимаю, что вы имеете в виду. У меня не было свойства id в классе-приверженце, потому что оно расширяет абстрактный класс суперкласса Demandeur, который имеет идентификатор. Так что в моей форме AdherentType я не поместил в нее свойство id, а добавил его напрямую в html-шаблон. Это объясняет, почему я пытаюсь получить его с помощью

$id = $request->request->get('id');

Поскольку я пытался использовать getData() и поскольку у моего объекта Adherent нет свойства id и т. д. метода setId(), я получил исключение:

Could not determine access type for property "id" in class "App\Entity\Adherent": Neither the property "id" nor one of the methods "addId()"/"removeId()", "setId()", "id()", "__set()" or "__call()" exist and have public access in class "App\Entity\Adherent".

что является правдой. До этого я пробовал добавить функцию, и все работало нормально, идентификаторы и отношения.

class AdherentType extends AbstractType
{
    /**
     *{@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {     
        $builder 
            ->add('id', IntegerType::class)
            ->add('nom', TextType::class, [
                'constraints' => [
                    new NotBlank(),
                    new Length(['max'=>50]),
                ]
            ])
            ->add('prenom', TextType::class, [
                'constraints' => [
                    new NotBlank(),
                    new Length(['max'=>50]),
                ]
            ])
            ->add('numSocietaire', IntegerType::class, [
                'constraints' => [
                    new NotBlank(),
                    new Length(['max'=>30]),
                ]
            ])
            ->add('anciennete', IntegerType::class, [
                'required' => 'false',
            ])
            ->add('contratActif', IntegerType::class, [
                'required' => 'false',
            ])
            ->add('dateNaiss', DateType::class, [
                'widget' => 'single_text',
                'required' => 'false',
            ])
            ->add('dateAdhes', DateType::class,[
                'widget' => 'single_text',
                'required' => 'false',
                'empty_data' => '',
            ])
            ->add('datePremMut', DateType::class, [
                'widget' => 'single_text',
                'required' => 'false',
            ])
            ->add('nbBenef', IntegerType::class, [
                'required' => 'false',
            ])
            ->add('nbIncidPaimt', IntegerType::class, [
                'required' => 'false',   
            ])
            ->add('detailContrat', DetailContratType::class)
            ->add('formule', EntityType::class, [
                'class' => Formule::class,
                'query_builder' => function (EntityRepository $er) {
                    return $er->createQueryBuilder('u')
                        ->orderBy('u.libelle', 'ASC');
                },
                'choice_label' => 'libelle',
                'required' => 'false',
            ])
            ->add('ancienneFormule', TextType::class, [
                'required' => 'false',
            ])
            ->add('resiliation', ResiliationType::class)
            ->add('save', SubmitType::class, ['label' => 'Créer l\'adhérent']);


    }

Я только что попытался добавить форму Demandeur (суперкласс) со свойством id в моей форме приверженца, но это наследование между Adherent и Demandeur, а не отношение.

class DemandeurType extends AbstractType
{
    /**
     *{@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {     
        $builder 
            ->add('id', IntegerType::class);
    }
}

class AdherentType extends AbstractType
{
    /**
     *{@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {     
        $builder 
            ->add('demandeur', EntityType::class, [
                'class' => Demandeur::class
            ])
            ....
    }
}

Я чего-то не понимаю, потому что это не работает так, как я думаю, должно...

РЕДАКТИРОВАТЬ : я добавил

parent::buildForm($builder, $options);

в моем классе приверженца у меня больше нет ошибок, но я все еще не хочу ничего обновлять, просто добавляя...

Обновлено: Мне удалось заставить это работать! Поэтому я поместил свое решение на случай, если оно когда-нибудь заинтересует кого-нибудь! Я создаю файл UpdateDemandeur.php в папке EventListener. Я поместил в него функцию preUpdate, но epty, потому что ничего не нужно было делать с таблицей Demandeur перед обновлением. Сложность была в моем контроллере. Поскольку я не отправлял никаких объектов в свои формы, когда формы были отправлены, объект, который я получил, был новым для события Symfony, если я использую функцию setId($id) из-за диспетчера сущностей. Мне пришлось использовать функцию слияния. Вот код, который я использую, и он работает.

        if ($request->isMethod('POST')){
            foreach($forms as $form){
                $form->handleRequest($request);
                if ( !$form->isSubmitted()) continue;

                if ($form->isValid()){
                    $demandeur = $form->getData();
                    $id = $request->request->get($type)['id'];
                    if ($id > 0) {
                        $demandeur->setId($id);
                        //Need to merge the new demandeur Object filled 
                        //with data from the form to update it in database
                        $dem = $em->merge($demandeur);

                    } else {
                        $em->persist($demandeur);
                    }
                    $em->flush();
                    return $this->redirectToRoute('demandeur_add');
                }
            }
        }

Надеюсь, это поможет кому-то!

Другие вопросы по теме