简体   繁体   中英

Symfony2 implement a form for OneToOne relation

I am trying to implement a one to one relation. Each User can be affected at a building (Etablissement for me). A building can have many people but each people can be affected at one building at most.

I have this error :

ContextErrorException: Catchable Fatal Error: Argument 1 passed to Intranet\\UserBundle\\Entity\\User::setUserEtab() must be an instance of Intranet\\RhBundle\\Entity\\Etablissement, array given, called in C:\\wamp\\www\\projet\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\PropertyAccess\\PropertyAccessor.php on line 360 and defined in C:\\wamp\\www\\projet\\src\\Intranet\\UserBundle\\Entity\\User.php line 322

The line 322 of User.php is :

public function setEtablissement(\Intranet\RhBundle\Entity\Etablissement $etablissement = null)

It occurs at the line $form->handleRequest($request); of my controller. This is my controller :

public function editerAction(Request $request, User $user){
    $form = $this->createForm(new EditerFormType, $user);
    if ($request->getMethod() == 'POST') {
        $form->handleRequest($request);
        die("ici");
        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($user);
            $this->get('session')->getFlashBag()->add('success', "L'utilisateur ". $user->getNom() ." ". $user->getPrenom() . " a été édité avec succès !");
            $em->flush();
            return $this->redirect($this->generateUrl('intranet_rh_homepage'));
        }else
            $this->get('session')->getFlashBag()->add('danger', "Erreur de formulaire !");  
    }
    return $this->render('IntranetRhBundle:User:editer.html.twig',array('user' => $user, 'form' => $form->createView()));
}

The die doesn't work. Before adding the form, it was working.

This is the EditForm :

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('email', 'email', array('label' => 'form.email', 'translation_domain' => 'FOSUserBundle')) 
        ->add('nom', 'text')
        ->add('prenom', 'text')
        ->add('naissance','date',array(
        'widget' => 'single_text',
        'format' => 'dd/MM/yyyy',
        'attr' => array('class' => 'date', 'readonly' => 'readonly')
        ))
        ->add('sexe', 'choice', array(
         'choices' => array('Homme' => 'Homme', 'Femme' => 'Femme'),
         'multiple' => false
        ))
        ->add('etablissement', new UserEtabType())
    ;
}

public function setDefaultOptions(OptionsResolverInterface  $resolver)
{
    $resolver->setDefaults(array('data_class' => 'Intranet\Userbundle\Entity\User'));
}

This is my UserEtab form :

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
    ->add('etablissement', 'entity', array('class' => 'IntranetRhBundle:Etablissement', 'property' => 'nom', 'empty_value' => 'Aucun', 'empty_data'  => -1, 'required' => false))
    ;
}

And my relation on User entity :

    /**
* @ORM\OneToOne(targetEntity="Intranet\RhBundle\Entity\Etablissement", cascade={"persist", "remove"})
**/
private $etablissement;

The form's view is okay, there is a select list with all the building and an empty value. But when I post, I have this error I can't understand and solve.

I have the setter and getter if User entity :

    /**
 * Set Etablissement
 *
 * @param \Intranet\RhBundle\EntityEtablissement $etablissement
 * @return User
 */
public function setEtablissement(\Intranet\RhBundle\Entity\Etablissement $etablissement = null)
{
    $this->etablissement = $etablissement;

    return $this;
}

/**
 * Get Etablissement
 *
 * @return \Intranet\RhBundle\Entity\Etablissement 
 */
public function getEtablissement()
{
    return $this->etablissement;
}

But when I var_dump $request->get('user')->get('etablissement') it doesn't work :

Error: Call to undefined method Intranet\\UserBundle\\Entity\\User::get() in C:\\wamp\\www\\projet\\src\\Intranet\\RhBundle\\Controller\\UserController.php line 69

And the building doesn't appear in var_dump of $request->get('user') .

EDIT :

I don't have a setDefaultOptions method for my UserEtabType because I don't know what I have to do. I tried to implements it but I have this kind of error :

The form's view data is expected to be an instance of class Intranet\\UserBundle\\Entity\\User, but is an instance of class Proxies__CG__\\Intranet\\RhBundle\\Entity\\Etablissement. 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 Proxies__CG__\\Intranet\\RhBundle\\Entity\\Etablissement to an instance of Intranet\\UserBundle\\Entity\\User.

For the new UserEtabType :

namespace Intranet\UserBundle\Form\Type;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class UserEtabType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
    ->add('etablissement', 'entity', array('class' => 'IntranetRhBundle:Etablissement', 'property' => 'nom', 'empty_value' => 'Aucun', 'empty_data'  => -1, 'required' => false))
    ;
}

public function setDefaultOptions(OptionsResolverInterface  $resolver)
{
    $resolver->setDefaults(array('data_class' => 'Intranet\UserBundle\Entity\User'));
}

public function getName()
{
    return 'intranet_userbundle_useretablissementtype';
}
}

Can you show the new UserEtabType() class ?

EDIT 1 : Try putting this line :

->add('etablissement', 'entity', array('class' => 'IntranetRhBundle:Etablissement', 'property' => 'nom', 'empty_value' => 'Aucun', 'empty_data' => -1, 'required' => false));

in the main EditForm

EDIT 2 : plus be careful :

$resolver->setDefaults(array('data_class' => 'Intranet\UserBundle\Entity\User'));

must be

$resolver->setDefaults(array('data_class' => 'Intranet\UserBundle\Entity\Etablissement'));

in your UserEtabType() class

Are you getting this error when you try to insert a record ? Or before that. For your information, setUserEtab() in the User entity expects an object of Etablissement, because of the one-to-one relationship. Passing the value of an array is not sufficient. Try passing the object of Etablissement it self (the selected object after performing dql).

Hope this helps someone.

Cheers!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM