2016-08-31 6 views
0

Ich habe ein Problem mit etwas, das ich denke, ist wahrscheinlich ziemlich einfach, aber die Ursache ist es, mir zu entkommen.Symfony Form with Doctrine Entity - Relation lädt nicht zum Bearbeiten

Ich habe zwei Entitäten, eine Organisation und ein Abonnement. Eine Organisation ist mit einem Abonnement verknüpft.

Ich möchte in der Lage sein, dies über ein Formular zu bearbeiten (Erstellung über Formular funktioniert bereits). Wenn ich Folgendes tun:

$organisation = $this->getDoctrine()->getRepository('AppBundle\Entity\Organisation') 
     ->findOneBy(array(
      'id' => $id 
     )); 

    $form = $this->createForm(new OrganisationType(), $organisation, array(
     'method' => 'POST' 
    )); 

    $form->submit($paramFetcher->all()); 

Ich erhalte eine Ausnahme, weil die Abonnement-Eigenschaft der Organisationseinheit nicht gesetzt ist (trotz einer vorbei, die ein Abonnement in die Form Standardwerte hat). Die Ausnahme ist, wie folgt:

Expected argument of type "AppBundle\Entity\Subscription", "NULL" given 

Dies wird offensichtlich durch die setSubscription Methode über die Organisation Einheit geworfen, aber ich bin mir nicht sicher, warum, wie die Form des int-Wertes auf ein Abonnement Einheit automatisch weitergegeben Umwandlung werden soll.

Mache ich hier etwas Dummes? Ich habe den untenstehenden Code beigefügt. Vielen Dank!

Die einfachste Controller-Aktion, die dieses Problem

public function testAction(Request $request) 
{ 

    $organisation = $this->getDoctrine()->getRepository('AppBundle\Entity\Organisation') 
     ->findOneBy(array('id' => 7)); 

    $form = $this->createForm(new OrganisationType(), $organisation); 

    $form->submit($request->request->all()); 

    return $this->render('test.html.twig', array(
     'testform' => $form->createView() 
    )); 

} 

Organisation.php

<?php 

namespace AppBundle\Entity; 

use Doctrine\Common\Collections\Collection; 
use Doctrine\ORM\Mapping as ORM; 
use JMS\Serializer\Annotation as JMS; 
use Gedmo\Mapping\Annotation as Gedmo; 
use Symfony\Component\Validator\Constraints as Assert; 

/** 
* Organisation 
* 
* @ORM\Table(name="organisation") 
* @ORM\Entity(repositoryClass="AppBundle\Repository\OrganisationRepository") 
*/ 
class Organisation 
{ 

const ENABLED = 1; 
const DISABLED = 2; 

/** 
* @var int 
* 
* @ORM\Column(name="id", type="integer") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="AUTO") 
* @JMS\Groups({"default", "list-organisation"}) 
*/ 
private $id; 

/** 
* @var string 
* 
* @ORM\Column(name="name", type="string", length=255) 
* @JMS\Groups({"default", "list-organisation"}) 
*/ 
private $name; 

/** 
* @var Subscription|null The subscription this organisation is currently linked to 
* @ORM\ManyToOne(targetEntity="Subscription", inversedBy="organisations") 
* @ORM\JoinColumn(name="subscription_id", referencedColumnName="id", onDelete="set null") 
* @JMS\Groups({"default", "list-organisation"}) 
*/ 
private $subscription; 

/** 
* @var Collection 
* @ORM\OneToMany(targetEntity="User", mappedBy="organisation") 
* @JMS\Groups({}) 
*/ 
private $users; 

/** 
* @var Collection 
* @ORM\OneToMany(targetEntity="Subgroup", mappedBy="organisation") 
* @JMS\Groups({"default"}) 
*/ 
private $subgroups; 

/** 
* @var string $enabled 
* 
* @ORM\Column(type="string") 
*/ 
private $enabled = self::ENABLED; 

/** 
* @var datetime $created 
* 
* @Gedmo\Timestampable(on="create") 
* @ORM\Column(type="datetime") 
* @JMS\Groups({"default", "list-organisation"}) 
*/ 
private $created; 

/** 
* @var datetime $updated 
* 
* @Gedmo\Timestampable(on="update") 
* @ORM\Column(type="datetime") 
* @JMS\Groups({"default", "list-organisation"}) 
*/ 
private $updated; 

/** 
* Get id 
* 
* @return integer 
*/ 
public function getId() 
{ 
    return $this->id; 
} 

/** 
* Set name 
* 
* @param string $name 
* @return Organisation 
*/ 
public function setName($name) 
{ 
    $this->name = $name; 

    return $this; 
} 

/** 
* Sets subscription 
* 
* @param Subscription $subscription 
* @return $this 
*/ 
public function setSubscription(Subscription $subscription) 
{ 
    $this->subscription = $subscription; 

    return $this; 
} 

/** 
* Gets subscription 
* 
* @return Subscription|null 
*/ 
public function getSubscription() 
{ 
    return $this->subscription; 
} 

/** 
* Sets enabled 
* 
* @param $enabled 
*/ 
public function setEnabled($enabled) 
{ 
    if (!in_array($enabled, array(self::ENABLED, self::DISABLED))) { 
     throw new \InvalidArgumentException('Invalid enabled status'); 
    } 

    $this->enabled = $enabled; 
} 

/** 
* Gets enabled 
* 
* @return string 
*/ 
public function getEnabled() 
{ 
    return $this->enabled; 
} 

/** 
* Get name 
* 
* @return string 
*/ 
public function getName() 
{ 
    return $this->name; 
} 

/** 
* Returns Users belonging to this organisation 
* 
* @return Collection 
*/ 
public function getUsers() 
{ 
    return $this->users; 
} 

public function __toString() 
{ 
    return $this->getName(); 
} 
} 

Subscription.php

<?php 

namespace AppBundle\Entity; 

use Doctrine\Common\Collections\Collection; 
use Doctrine\ORM\Mapping as ORM; 
use JMS\Serializer\Annotation as JMS; 
use Gedmo\Mapping\Annotation as Gedmo; 

/** 
* Organisation 
* 
* @ORM\Table(name="subscription") 
* @ORM\Entity(repositoryClass="AppBundle\Repository\SubscriptionRepository") 
*/ 
class Subscription 
{ 
/** 
* @var int 
* 
* @ORM\Column(name="id", type="integer") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="AUTO") 
* @JMS\Groups({"default", "list-organisation"}) 
*/ 
private $id; 

/** 
* @var string 
* 
* @ORM\Column(name="name", type="string", length=255) 
* @JMS\Groups({"default", "list-organisation"}) 
*/ 
private $name; 

/** 
* @var Collection 
* @ORM\OneToMany(targetEntity="Organisation", mappedBy="subscription") 
* @JMS\Groups({"default"}) 
*/ 
private $organisations; 

/** 
* @var datetime $created 
* 
* @Gedmo\Timestampable(on="create") 
* @ORM\Column(type="datetime") 
* @JMS\Groups({"default"}) 
*/ 
private $created; 

/** 
* @var datetime $updated 
* 
* @Gedmo\Timestampable(on="update") 
* @ORM\Column(type="datetime") 
* @JMS\Groups({"default"}) 
*/ 
private $updated; 

/** 
* Get id 
* 
* @return integer 
*/ 
public function getId() 
{ 
    return $this->id; 
} 

/** 
* Set name 
* 
* @param string $name 
* @return Subscription 
*/ 
public function setName($name) 
{ 
    $this->name = $name; 

    return $this; 
} 

/** 
* Get name 
* 
* @return string 
*/ 
public function getName() 
{ 
    return $this->name; 
} 

/** 
* Returns Organisations with this subscription type 
* 
* @return Collection 
*/ 
public function getOrganisations() 
{ 
    return $this->organisations; 
} 

/** 
* @return string 
*/ 
public function __toString() 
{ 
    return $this->getName(); 
} 
} 
repliziert

OrganisationType.php

<?php 

namespace AppBundle\Form; 

use Doctrine\Common\Persistence\ObjectManager; 
use Symfony\Bridge\Doctrine\Form\Type\EntityType; 
use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolver; 

class OrganisationType extends AbstractType 
{ 
private $manager; 

public function __construct(ObjectManager $objectManager) 
{ 
    $this->manager = $objectManager; 
} 

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder->add('name'); 
    $builder->add('subscription', EntityType::class, array(
     'class' => 'AppBundle\Entity\Subscription' 
    )); 

} 

public function configureOptions(OptionsResolver $resolver) 
{ 
    $resolver->setDefaults(array(
     'data_class' => 'AppBundle\Entity\Organisation', 
     'csrf_protection' => false 
    )); 
} 
} 
+1

Erstens, warum verwenden Sie einen DataTransformer für dieses Entitätsfeld? Symfony ist in der Lage, eine Ganzzahl (die vom Auswahlfeld Ihres Formulars bereitgestellt wird) in ein Objekt umzuwandeln, solange Sie die zu verwendende Klasse angeben, die Sie in den Feldoptionen angegeben haben. Zweitens, kannst du bitte die Ausnahme werfen? – VaN

+0

@VaN Hallo, ich hatte den Transformator in nur um zu überprüfen, ob es konvertiert wurde. Es ist unnötig und ich habe es seitdem entfernt. Ich habe meinen Beitrag bearbeitet, um die tatsächliche Ausnahme anzuzeigen. Danke für deine Hilfe, diese macht mich verrückt! –

+0

Die einzige Sache, die ich nicht kenne, ist Ihre Weise, Formsubmission zu behandeln. Ich habe nie '$ form-> submit ($ paramFetcher-> all())' verwendet. Gemäß der Dokumentation ist die Art und Weise, mit der das Formular bearbeitet wird, die folgende: $ form-> handleRequest ($ request); if ($ form-> isSubmitted() && $ form-> isValid()) { $ organisation = $ form-> getData(); // ... eine Aktion ausführen, z. B. Speichern der Aufgabe in der Datenbank " siehe http://symfony.com/doc/current/forms.html#handling-form-submissions – VaN

Antwort

0

Auf einem frischen Symfony 3.1 funktioniert dies wie ein Zauber (und dies ist der empfohlene Weg Form Vorlage zu handhaben, wie in einem früheren Kommentar angegeben):

public function testAction(Request $request) 
{ 
    $organisation = $this->getDoctrine()->getRepository('AppBundle\Entity\Organisation') 
     ->find(1); 

    $form = $this->createForm(OrganisationType::class, $organisation); 

    $form->handleRequest($request); 

    if ($form->isSubmitted() && $form->isValid()) { 
     $this->getDoctrine()->getManager()->persist($organisation); 
     $this->getDoctrine()->getManager()->flush(); 

     die('saved into database.'); 
    } 

    return $this->render('test.html.twig', array(
     'testform' => $form->createView() 
    )); 

} 
+0

Vielen Dank für die Mühe. Ich habe die Quelle nicht gefunden, obwohl ich vermute, dass es etwas mit Serialisierungsgruppen oder etwas zu tun hat. Ich musste vorerst weitermachen, aber ich werde die Frage mit der Antwort aktualisieren, wenn ich zurückkomme. –