Создать, если данные не существуют с Symfony 4 - PullRequest
0 голосов
/ 10 июля 2019

У меня есть форма, которую пользователь заполнил именем. Основываясь на этом имени, я делаю 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? Или я должен сделать это вручную?

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

Ответы [ 2 ]

0 голосов
/ 11 июля 2019

Хорошо, я понимаю, что вы имеете в виду.У меня не было свойства 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);

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

РЕДАКТИРОВАТЬ: Мне удалось заставить это работать!Поэтому я поставил свое решение на тот случай, если оно кого-нибудь заинтересует!Я создаю файл UpdateDemandeur.php в папке EventListener.Я вставил в него функцию preUpdate, но epty, потому что перед обновлением ничего не нужно было делать с таблицей Демандера.Сложная часть была в моем контроллере.Поскольку я не отправлял какой-либо объект в свои формы, при отправке форм объект, который я получил, был новым для события 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');
                }
            }
        }

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

0 голосов
/ 10 июля 2019

Вместо создания нового рекламодателя $ вы можете загрузить конкретный рекламодатель из своей базы данных. Вручную, как в документации , но вы можете использовать Автоматическая выборка объектов (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", если я хорошо понял, это похоже на то, что вы хотите достичь.

EDIT

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

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

EDIT

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

...