在EntityType字段中创建与实体关联的新实体

时间:2017-07-06 14:53:38

标签: forms symfony doctrine

我正在使用Doctrine处理Symfony 3。在我的音乐学校项目中,我有3个实体(Morceau(Tune翻译),Eleve(学生翻译),乐器)。有了一个表格,我想创建一个新的Morceau合作伙伴,与现有乐器的新Eleve合作伙伴。

现在,我有一个问题是将Eleve与现有的乐器相关联,这是一个EntityType(所有乐器的列表):

可捕获的致命错误:类AppBundle \ Entity \ Instrument的对象无法转换为字符串

问题是我不想创建新的乐器ID。

协会是:Morceau(@ ORM / ManyToOne $ eleve),Eleve(@ ORM / ManyToOne $乐器),乐器(带$ id和$ nomInstrument)。

我的表格:

MorceauType:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('titre', TextType::class)
            ->add('compositeur', TextType::class)
            ->add('formation', TextType::class)
            ->add('duree', IntegerType::class)
            ->add('materiel', TextType::class)
            ->add('accompagnementPiano', ChoiceType::class, 
                array('choices' => array('Oui' => True, 'Non' => False)))   
            ->add('eleve', EleveType::class) 
            ->add('save', SubmitType::class)    ;
}

EleveType:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('nomEleve', TextType::class)
            ->add('prenomEleve', TextType::class)
            ->add('instrument', InstrumentType::class)
                                ;
}

InstrumentType:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('nomInstrument', EntityType::class, array('class' => 'AppBundle:Instrument', 
                                                                        'choice_label' => 'nomInstrument'))
    ;
}

我的控制器:

public function addTuneAction(Request $request)
{   

    // On récupère le formulaire Morceaux
    $morceau = new Morceau();


    $form = $this->createForm(MorceauType::class, $morceau);

    //On vérifie les valeurs
    if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()) {  
        $em = $this->getDoctrine()->getManager();
        $em->persist($morceau);
        $em->flush();

        $request->getSession()->getFlashBag()->add('notice', 'Morceau enregistré');

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

    // on retourne la vue
    return $this->render('snippets/addTune.html.twig', array('morceau' => $form->createView()));
}

非常感谢!

这是我的实体:

Morceau:

/**
 * Morceau
 *
 * @ORM\Table(name="Morceau")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\MorceauRepository")
 */
class Morceau
{
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="titre", type="string", length=255)
 */
private $titre;

/**
 * @var string
 *
 * @ORM\Column(name="compositeur", type="string", length=255)
 */
private $compositeur;

/**
 * @var string
 *
 * @ORM\Column(name="formation", type="string", length=255)
 */
private $formation;

/**
 * @var int
 *
 * @ORM\Column(name="duree", type="smallint")
 */
private $duree;

/**
 * @var string
 *
 * @ORM\Column(name="materiel", type="string", length=255)
 */
private $materiel;

/**
 * @var bool
 *
 * @ORM\Column(name="accompagnementPiano", type="boolean")
 */
private $accompagnementPiano;

/**
*
* @ORM\ManyToOne(targetEntity="Eleve", cascade={"persist"})
* @ORM\JoinColumn(name="eleve_id", referencedColumnName="id")
*/
private $eleve;

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

/**
 * Set titre
 *
 * @param string $titre
 *
 * @return morceau
 */
public function setTitre($titre)
{
    $this->titre = $titre;

    return $this;
}

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

/**
 * Set compositeur
 *
 * @param string $compositeur
 *
 * @return morceau
 */
public function setCompositeur($compositeur)
{
    $this->compositeur = $compositeur;

    return $this;
}

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

/**
 * Set formation
 *
 * @param string $formation
 *
 * @return morceau
 */
public function setFormation($formation)
{
    $this->formation = $formation;

    return $this;
}

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

/**
 * Set duree
 *
 * @param integer $duree
 *
 * @return morceau
 */
public function setDuree($duree)
{
    $this->duree = $duree;

    return $this;
}

/**
 * Get duree
 *
 * @return int
 */
public function getDuree()
{
    return $this->duree;
}

/**
 * Set materiel
 *
 * @param string $materiel
 *
 * @return morceau
 */
public function setMateriel($materiel)
{
    $this->materiel = $materiel;

    return $this;
}

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

/**
 * Set accompagnementPiano
 *
 * @param boolean $accompagnementPiano
 *
 * @return morceau
 */
public function setAccompagnementPiano($accompagnementPiano)
{
    $this->accompagnementPiano = $accompagnementPiano;

    return $this;
}

/**
 * Get accompagnementPiano
 *
 * @return bool
 */
public function getAccompagnementPiano()
{
    return $this->accompagnementPiano;
}

/**
 * Set eleve
 *
 * @param \AppBundle\Entity\Eleve $eleve
 *
 * @return Morceau
 */
public function setEleve(\AppBundle\Entity\Eleve $eleve = null)
{
    $this->eleve = $eleve;

    return $this;
}

/**
 * Get eleve
 *
 * @return \AppBundle\Entity\Eleve
 */
public function getEleve()
{
    return $this->eleve;
}

}

Eleve:

/**
 * eleve
 *
 * @ORM\Table(name="Eleve")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\EleveRepository")
 */
class Eleve
{
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="nomEleve", type="string", length=30)
 */
private $nomEleve;

/**
 * @var string
 *
 * @ORM\Column(name="prenomEleve", type="string", length=50)
 */
private $prenomEleve;

/**
*
* @ORM\ManyToOne(targetEntity="Instrument", cascade={"persist"})
* @ORM\JoinColumn(name="instrument_id", referencedColumnName="id")
*/
private $instrument;


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

/**
 * Set nomEleve
 *
 * @param string $nomEleve
 *
 * @return eleve
 */
public function setNomEleve($nomEleve)
{
    $this->nomEleve = $nomEleve;

    return $this;
}

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

/**
 * Set prenomEleve
 *
 * @param string $prenomEleve
 *
 * @return eleve
 */
public function setPrenomEleve($prenomEleve)
{
    $this->prenomEleve = $prenomEleve;

    return $this;
}

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

/**
 * Set instrument
 *
 * @param \AppBundle\Entity\Instrument $instrument
 *
 * @return Eleve
 */
public function setInstrument(\AppBundle\Entity\Instrument $instrument)
{
    $this->instrument = $instrument;

    return $this;
}

/**
 * Get instrument
 *
 * @return \AppBundle\Entity\Instrument
 */
public function getInstrument()
{
    return $this->instrument;
}

}

仪器:

/**
 * Instrument
 *
 * @ORM\Table(name="Instrument")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\InstrumentRepository")
 */
class Instrument
{
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="nomInstrument", type="string", length=50)
 */
private $nomInstrument;


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

/**
 * Set nomInstrument
 *
 * @param string $nomInstrument
 *
 * @return instrument
 */
public function setNomInstrument($nomInstrument)
{
    $this->nomInstrument = $nomInstrument;

    return $this;
}

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

}

更新#1:

当我查看Profiler时,我可以看到问题所在。如果你看一下nomInstrument,它是一个整数,但它应该是我的实体的一个字符串。在此示例中,3是所选仪器的ID ...

appbundle_morceau : [▼
  "titre" => "Leapfrog"
  "compositeur" => "Ravel"
  "formation" => "duo"
  "duree" => "5"
  "materiel" => "micro"
  "accompagnementPiano" => "1"
  "eleve" => [▼
    "nomEleve" => "Georges"
    "prenomEleve" => "Gauthier"
    "instrument" => [▼
      "nomInstrument" => "3"
    ]
  ]
  "save" => ""
  "_token" => "m3priXJyFUHCGpP58twZx3yyeS1eb-yeWGtIWrv6Llc"
]

更新#2:

当我尝试在没有表单的情况下执行相同的操作时,它可以正常工作。我在控制器中设置了这样的值:

public function testAction(Request $request)
{

    $repository = $this->getDoctrine()
                       ->getManager()
                       ->getRepository('AppBundle:Instrument');

    $instrumentId = $repository->find(3);

    $morceau = new Morceau();
    $eleve = new Eleve();

    $eleve->setNomEleve('Alex');
    $eleve->setPrenomEleve('Jean');
    $eleve->setInstrument($instrumentId);

    $morceau->setTitre('Bolero');
    $morceau->setCompositeur('Ravel');
    $morceau->setFormation('duo');
    $morceau->setDuree('4');
    $morceau->setMateriel('pupitre');
    $morceau->setAccompagnementPiano(true);
    $morceau->setEleve($eleve);



    $em = $this->getDoctrine()->getManager();
    $em->persist($morceau);
    $em->flush();

2 个答案:

答案 0 :(得分:0)

将实体加载到表单时,您需要确保您的Entity类具有__toString()方法。这就是Symfony用于" name" option元素的字段。

答案 1 :(得分:0)

经过漫长的一天,我有解决方案。我只需删除InstrumentType并将EntityType直接放在我的EleveType中,就像那样:

public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('nomEleve', TextType::class)
                ->add('prenomEleve', TextType::class)
                ->add('instrument', EntityType::class, array('class' => 'AppBundle:Instrument', 
                                                                            'choice_label' => 'nomInstrument'))
                                    ;
    }