2016-08-31 4 views
0

Erstellen eines internen API-Endpunkts, der es einem anderen Dienst ermöglicht, bestimmte Felder für Benutzer zu aktualisieren, die durch E-Mail-Adressen identifiziert werden. Wenn der Benutzer nicht existiert, muss er erstellt werden.Symfony Form CollectionType mit API-Beitrag neuer/bestehender Entitäten

Der Code funktioniert einwandfrei, wenn nur neue Benutzer gesendet werden.

Dies ist die POST-Anforderung an den API-Endpunkt.

[ 
    { 
     "email":"[email protected]", 
     "favouriteFood": "pizza" 
    }, 
    { 
     "email":"[email protected]", 
     "favouriteFood": "sweets" 
    } 
] 

Controller-Aktion

public function postUsersAction(Request $request) 
{ 
    $form = $this->createForm(UserCollectionType::class); 
    $form->submit(['users' => json_decode($request->getContent(), true)], true); 

    if (!$form->isValid()) { 
     return $form; 
    } 

    /** @var User $user */ 
    foreach ($form->getData()['users'] as $user) { 
     $this->userManager->updateUser($user); 
    } 

    $this->em->flush(); 

    return $form->getData()['users']; 
} 

UserCollectionType

class UserCollectionType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('users', 'collection', [ 
      'allow_add' => true, 
      'by_reference' => false, 
      'type' => UserType::class 
     ]); 
    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults([ 
      'csrf_protection' => false, 
      'cascade_validation' => true 
     ]); 
    } 

    public function getBlockPrefix() 
    { 
     return ''; 
    } 
} 

Usertype

class UserType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('email') 
      ->add('favouriteFood', TextType::class); 
    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults([ 
      'data_class' => User::class, 
      'validation_groups' => ['user_api'], 
      'cascade_validation' => true 
     ]); 
    } 
} 

Wie kann ich den obigen Code aktualisieren, damit sie sehen wird überprüfen, ob der Benutzer vorhanden ist zuerst, sonst co noch ein neues erstellen, wie es derzeit funktioniert.

Ich hätte angenommen, dass ein DataTransformer verwendet worden sein könnte, aber nicht genau wie.

EDIT: Vorgeschlagene Lösung von ShylockTheCamel

Im Inneren des Controllers.

Antwort

0

Wenn ich richtig verstehe, existieren Ihre Benutzereinheit (en), wenn Sie die foreach-Schleife eingeben. Sie müssen sie also im Formularerstellungsprozess erstellen. In diesem Fall überprüfen Sie die Existenz eines Benutzers in einem Ihrer Formularvalidatoren.

+0

Ich habe die Frage mit wie ich Ihre vorgeschlagene Lösung anwenden würde aktualisiert. Fühlt sich nur ein bisschen hacky an und vermied es von vornherein. War neugierig, ob es eine bessere Lösung gibt, wie zum Beispiel, wo Symfony den Benutzer basierend auf 'data_class' erstellt. – Nick

+0

Ich habe nicht vorgeschlagen, die Existenz eines Benutzers innerhalb des Controllers selbst zu überprüfen (was ziemlich dreckig ist)) aber innerhalb einer Validator-Klasse. Ich nehme an, Sie validieren das Formular, d. H. Die Felder E-Mail und favoriteFood gegen einige Einschränkungen, nicht wahr? Was ich vorgeschlagen habe, ist das Hinzufügen einer Einschränkung für E-Mails, um beispielsweise deren Nicht-Existenz zu überprüfen. Wenn der Test erfolgreich ist, führen Sie zusammen mit Ihrer anderen Einschränkung Ihre aktuellen Aktionen für einen neuen Benutzer aus. Wenn dies fehlschlägt, überprüfen Sie, ob die Nicht-Existenz-Einschränkung fehlgeschlagen ist und nicht die anderen, und wenn dies der Fall ist, handelt es sich um einen vorhandenen Benutzer. – ShylockTheCamel

+0

Interessant, ich sehe nicht, wie das funktionieren würde. Wie bekomme ich eine bevölkerte Instanz in meine Controller-Schleife, da Validatoren keine Daten zurückgeben? – Nick

Verwandte Themen