Passing more than one entity object to formBuilder

New topics about Symfony 2 should go here

Moderators: dcobalt, tiagojsag

Passing more than one entity object to formBuilder

Postby thorinkor » Thu Apr 12, 2012 8:42 pm

Hi!

I've got a big problem. I want to pass two entities to the form builder, as I want one form to create client and user account at once. Everything is ok until I'm trying to process the post data. When I add validation, it fails + there is no data in new entities. Seems like there is a problem with binding the form to entities, but I don't know why. My form and action look like this:

form
Code: Select all
class RegisterUser extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder->add('username', 'text', array('label' => 'Nazwa użytkownika*')) //from User entity
            ->add('password', 'password', array('label' => 'Hasło*'))  //from User entity
            ->add('email', 'text', array('label' => 'Adres e-mail*'))  //from User entity
            ->add('companyName', 'text', array('label' => 'Nazwa firmy*'))  //from Client entity
            ->add('companyAddress', 'text', array('label' => 'Adres firmowy'))  //from Client entity
            ->add('companyPhone', 'text', array('label' => 'Telefon firmowy'))  //from Client entity
            ->add('type', 'entity', array('class' => 'CoreUserBundle:Type', 'label' => 'Sektor działalności'));  //from Client entity

      return $builder->getForm();
    }

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


registerAction
Code: Select all
public function registerAction() {

      $newUser = new \Core\UserBundle\Entity\User();
      $newClient = new \Core\UserBundle\Entity\Client();
      
//here I'm passing two entities in array to the formBuilder, and I have access to the fields in the builder, everything seems to be ok
      $form = $this->createForm(new \Core\AuthBundle\Form\Registration\RegisterUser(), array($newUser, $newClient));
      $request = $this->getRequest();
      
      if ($request->getMethod() == 'POST') {
         $form->bindRequest($request);
         
         if ($form->isValid()) {
            // but when I'm setting validation, it fails. Seems like there is a problem with binding the form to entities, but I don't know why. I guess it has a problem as I passed two entities in array, and not one
//if I'd try to echo $newUser->getUsername() here, it's empty.
         }
      }

      return $this->render('CoreAuthBundle:Default:registration.html.twig', array('form' => $form->createView()));
   }


Can somebody help me on that one? I really don't know why it doesn't want to bind my post data correctly ;/ When I'm passing only one entity to the form, everything seems to be fine.
thorinkor
Junior Member
 
Posts: 23
Joined: Tue Feb 21, 2012 12:08 pm

Re: Passing more than one entity object to formBuilder

Postby cerad2 » Sat Apr 14, 2012 1:52 am

Make three form types:
MasterType
ClientType
AccountType

Embed the sub types in the master then pass your two entities in an arrray.

Another useful approach is to create a new object (not an entity) which contains client/account objects and then provides an interface to route the getter/setters to the appropriate object. This facade approach basically lets you flatten a complex object graph.
cerad2
Faithful Member
 
Posts: 202
Joined: Thu Jul 14, 2011 2:25 am

Re: Passing more than one entity object to formBuilder

Postby thorinkor » Sat Apr 14, 2012 12:04 pm

Could You please tell more about the 1st option? How to embed two sub forms in master? Some piece of code would be very usefull ;)

//EDIT:
Made an approach, but still it seems like the request can't be bound ;/
Controller:
Code: Select all
public function registerAction() {

      $newUser = new \Core\UserBundle\Entity\User();
      $newClient = new \Core\UserBundle\Entity\Client();
      
      $form = $this->createForm(new \Core\AuthBundle\Form\Registration\RegisterUser(), array($newUser, $newClient));
      $request = $this->getRequest();
      
      if ($request->getMethod() == 'POST') {
         $form->bindRequest($request);
         
         if ($form->isValid()) {
            $em = $this->getDoctrine()->getEntityManager();
            $newUser->setIsActive(1);
            $em->persist($newUser);
            echo 'user:'.$newUser->getUsername(); //doesn't show username, that has been set in the form and sent by post..
            exit();
         }
      }

      return $this->render('CoreAuthBundle:Default:registration.html.twig', array('form' => $form->createView()));
   }


UserType
Code: Select all
<?php

// src/Core/AuthBundle/Form/Type/UserType.php

namespace Core\AuthBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;

class UserType extends AbstractType {

   public function buildForm(FormBuilder $builder, array $options) {
      $builder->add('username', 'text', array('label' => 'Nazwa użytkownika*'))
            ->add('password', 'password', array('label' => 'Hasło*'))
            ->add('email', 'text', array('label' => 'Adres e-mail*'));

      return $builder->getForm();
   }

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

}

?>


ClientType
Code: Select all
<?php

// src/Core/AuthBundle/Form/Type/ClientType.php

namespace Core\AuthBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;

class ClientType extends AbstractType {

   public function buildForm(FormBuilder $builder, array $options) {
      $builder->add('companyName', 'text', array('label' => 'Nazwa firmy*'))
            ->add('companyAddress', 'text', array('label' => 'Adres firmowy'))
            ->add('companyPhone', 'text', array('label' => 'Telefon firmowy'))
            ->add('type', 'entity', array('class' => 'CoreUserBundle:Type', 'label' => 'Sektor działalności'));

      return $builder->getForm();
   }

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

}
?>


Master form
Code: Select all
<?php

// src/Core/AuthBundle/Form/Registration/RegisterUser.php

namespace Core\AuthBundle\Form\Registration;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;

class RegisterUser extends AbstractType {

   public function buildForm(FormBuilder $builder, array $options) {
      $builder->add('User', new \Core\AuthBundle\Form\Type\UserType($options))
            ->add('Client', new \Core\AuthBundle\Form\Type\ClientType($options));

      return $builder->getForm();
   }

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

}

?>


Could someone take a look at it please? I'm kinda new to Symfony and I'm stuck in project that I need to finish this week ;/

EDIT://
This is just unbelieveable! I found the problem... and it's one of those "WTF" ones -.- The only thing that needed changing was the array keys ( named User and Client):
Code: Select all
array($newUser, $newClient) //keys: 0, 1 -> WRONG!
array('User'=>$newUser, 'Client'=>$newClient) //keys: User, Client - CORRECT!

The answer to kinda big problem is lame as always. I just can't believe it... 3 days, grrrr!
thorinkor
Junior Member
 
Posts: 23
Joined: Tue Feb 21, 2012 12:08 pm


Return to General Symfony 2 discussion

Who is online

Users browsing this forum: No registered users and 6 guests