Bonsoir à tous,

J'ai déjà posé cette question sur deux autres forum connu, mais personne ne semble être en mesure de m'aider alors que ce problème me semble basique, limite " cas d'école ". :/

Je souhaite réaliser un formulaire imbriqué, la manière la plus simple qu'il soit : j'ai une entité "cabinet", laquelle doit imbriquer une "version". A terme, il y aura plusieurs versions mais ce formulaire la doit n'en ajouter qu'une seule, la première. J'ai donc fait ceci :

Formulaire Cabinet :

class CabinetType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('versions', new CabinetVersionType())
            ->add('submit', 'submit', array(
                'label' => 'Valider'
            ))
        ;
    }
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'LogicielBundle\Entity\Cabinet'
        ));
    }
    public function getName()
    {
        return 'logiciel_cabinet_form';
    }
}

Formulaire version :

class CabinetVersionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('libelle', 'text', array(
                'label' => 'Libellé',
                'max_length' => 55
            ))
        ;
    }
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'LogicielBundle\Entity\CabinetVersion'
        ));
    }
    public function getName()
    {
        return 'logiciel_cabinet_version_form';
    }
}

Dès que j'affiche le formulaire, j'ai cette erreur qui est renvoyée : "The form's view data is expected to be an instance of class LogicielBundle\Entity\CabinetVersion, but is an instance of class Doctrine\Common\Collections\ArrayCollection. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms an instance of class Doctrine\Common\Collections\ArrayCollection to an instance of LogicielBundle\Entity\CabinetVersion."

Je comprends bien qu'il me demande de mettre data_class à null ; d'ailleurs quand je le fait le formulaire s'affiche, mais dans ce cas je casse la relation à l'entité il me semble. :/

J'ai regardé sur les forums, certains préconisent d'utiliser un formulaire de type collection + javascript mais ça ne semble pas adapté, puisque je ne souhaite ajouter qu'une seule version, ce serait dommage d'utiliser du javascript pour ça.

A titre informatif, voici l'entité Cabinet :

class Cabinet
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\OneToMany(targetEntity="LogicielBundle\Entity\CabinetVersion", mappedBy="cabinet", cascade={"persist"})
     */
    private $versions;
    public function __construct()
    {
        $this->versions = new \Doctrine\Common\Collections\ArrayCollection();
    }
    public function getId()
    {
        return $this->id;
    }
    public function addVersion(\LogicielBundle\Entity\CabinetVersion $versions)
    {
        $this->versions[] = $versions;
        $versions->setCabinet($this);        
        return $this;
    }
    public function removeVersion(\LogicielBundle\Entity\CabinetVersion $versions)
    {
        $this->versions->removeElement($versions);
    }
    public function getVersions()
    {
        return $this->versions;
    }
}

Et enfin l'entité CabinetVersion :


class CabinetVersion
{

    use Adresse;
    use DateVersion;
    use DateReference;
    //use Fichier;

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="LogicielBundle\Entity\Cabinet", inversedBy="versions")
     * @ORM\JoinColumn(nullable=false)
     */
    private $cabinet;

    /**
     * @var string
     *
     * @ORM\Column(name="libelle", type="string", length=55)
     * @Assert\NotBlank()
     */
    private $libelle;

    public function getId()
    {
        return $this->id;
    }
    public function setLibelle($libelle)
    {
        $this->libelle = $libelle;

        return $this;
    }
    public function getLibelle()
    {
        return $this->libelle;
    }
    public function setCabinet(\LogicielBundle\Entity\Cabinet $cabinet)
    {        
        $this->cabinet = $cabinet;

        return $this;
    }
    public function getCabinet()
    {
        return $this->cabinet;
    }
}

Merci beaucoup à ceux qui pourront m'aider / m'éclairer :)

2 réponses


Sujet déplacé dans la catégorie Symfony 2

Bonjour, il s'agit d'une relation OneToMany
En écrivant : ->add('versions', new CabinetVersionType()), tu n'as qu'un seul formulaire.
Voici comment va agir symfony :
il voit le champ versions.
Il va récupérer les données en utilisant par défaut le getVersions()
Que te renvoie getVersions ? Un ArrayCollection (vide ou contenant des CabinetVersion.)
Du coup, tu devineras qu'il n'arrivera pas à remplir ton formulaire CabinetVersionType, étant donné que tu as une liste et pas un seul élément. Il faudrait plusieurs formulaires CabinetVersionType.

Si tu as une relation oneToMany, il faut t'orienter vers un form embed.
->add('versions', 'collection', array('type' => new CabinetVersionType())