Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entities passed to the choice field must be managed

Tags:

php

symfony

I create a new object and bind it to a form. The user fills out the form and goes to a preview page. I store the user responses in the session.

The problem crops up when I try to reload the object from the session when the user goes back to edit the form. I get :

Error: the Entities passed to the choice field must be managed.

Anyone have an idea of where i might be going wrong? Heres the code for the controllers.

public function previewdealAction(Request $request){

    $session = $this->getRequest()->getSession();
    $coupon = $session->get('coupon');
    $form = $this->createForm(new CouponType(), $coupon);

    if ($request->getMethod() == 'POST') {

        //bind the posted form values
        $form->bindRequest($request);

        //once a valid form is submitted ...
        if ($form->isValid()){
           //Proceed to Previewing deal
            $file = $coupon->getImage();
            $file->upload();
            $session->set('coupon', $coupon);

            $repository = $this->getDoctrine()
            ->getRepository('FrontendUserBundle:Coupon');
            $coupons = $repository->findAll();

            return $this->render('FrontendHomeBundle:Merchant:dealpreview.html.twig', array('coupon'=>$coupon, 'coupons'=>$coupons));

        }
    }

}
public function builddealAction(Request $request){

    $em = $this->get('doctrine')->getEntityManager();
    $user = $this->container->get('security.context')->getToken()->getUser();

    //check for a coupon session variable
    $session = $this->getRequest()->getSession();

    $coupon = $session->get('coupon');

    //If coupon is not set
    if($coupon == NULL){
        $coupon = new Coupon();
        $date = new \DateTime(date("Y-m-d H:i:s"));
        $coupon->setStartdate($date);
        $coupon->setPosterid($user);
        $session->set('coupon', $coupon);
    }

    $form = $this->createForm(new CouponType(), $coupon);
    return $this->render('FrontendHomeBundle:Merchant:builddeal.html.twig', array(
        'form' => $form->createView(),
    ));
}

--

namespace Frontend\HomeBundle\Form\Type;

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

class CouponType extends AbstractType {

public function buildForm(FormBuilder $builder, array $options) {
    $builder->add('couponname', 'text');
    $builder->add('description', 'textarea');
    $builder->add('price', 'money', array('currency' => 'USD'));
    $builder->add('originalprice', 'money', array('currency' => 'USD'));
    $builder->add('maxlimit', 'integer');
    $builder->add('maxper', 'integer');
    $builder->add('startdate', 'date', array(
        'years' => array(2011, 2012, 2013, 2014),

    ));
    $builder->add('duration', 'choice', array(
        'choices'   => array(
            '3'   => 3,
            '7'   => 7,
            '14' => 14,
            '30'   => 30,
            '60'   => 60,
            '90'   => 90,
            ),
        'expanded'  => false,
        'multiple'  => false,
        ));
    $builder->add('expirationdate', 'choice', array(
        'choices'   => array(
            '30'   => 30,
            '60'   => 60,
            '90' => 90,
            '180'   => 180,
            ),
        'expanded'  => false,
        'multiple'  => false,
        ));
    $builder->add('tip', 'integer');
    $builder->add('salestax', 'choice', array(
       'choices'   => array(
            'included'   => 'Sales tax is included and will be remitted BY YOU at the appropriate tax jurisdiction',
            'exempt'   => 'Sales tax is exempt according to seller\'s tax jurisdiction',
            'collected' => 'Sales tax will be collected BY YOU at time of deal redemption',
            ),
        'expanded'  => true,
        'multiple'  => false,
    ));
    $builder->add('signature', 'text');
    $builder->add('city', 'entity', array(
        'class' => 'Frontend\\UserBundle\\Entity\\Cities',
        'expanded' => false,
        'multiple' => false,

    ));
    $builder->add('category', 'entity', array(
        'class' => 'Frontend\\UserBundle\\Entity\\Category',
        'expanded' => false,
        'multiple' => false,
    ));
    $builder->add('address', new AddressType());
    $builder->add('image', new DocumentType());
    $builder->add('maxper', 'choice', array(
        'choices'   => array(
            '1'   => 1,
            '2'   => 2,
            '3' => 3,
            '4'   => 4,
            '5'   => 5,
            '6'   => 6,
            '7' => 7,
            '8'   => 8,
            '9'   => 9,
            '10'   => 10,
            ),
        'expanded'  => false,
        'multiple'  => false,
        ));

}

public function getDefaultOptions(array $options) {
    return array(
        'data_class' => 'Frontend\UserBundle\Entity\Coupon',
    );
}
public function getName()
{
    return 'user';
}

}

heres the coupon type class

like image 888
michael Avatar asked Sep 19 '11 16:09

michael


3 Answers

I was experiencing the same problem - I was retrieving data from a form using getData() and storing in the session. Later on, after a redirect, I was attempting to repopulate another instance of the same form using setData().

I experienced no issues with native fields. However, when my form included an entity I was receiving the same dreaded message "Entities passed to the choice field must be managed".

After some head scratching the issue revealed itself to be pretty straightforward (aren't they all?). After a redirect, the entity has become detached; the solution is simply to re-include the entity into the EntityManager using EntityManager::merge(), thus reinstating the entity as a managed object :)

// an array of form data from session
$entity = $data['my_entity'];

// merge() returns the managed entity
$entity = $this->getDoctrine()->getEntityManager()->merge($entity);

// update the form data array
$data['my_entity'] = $entity;

// Create form with form data 
$form = $this->createForm(new MyFormType(), $data);

http://www.doctrine-project.org/api/orm/2.0/doctrine/orm/entitymanager.html

Hope this helps!

like image 99
Darragh Enright Avatar answered Nov 12 '22 20:11

Darragh Enright


It's not relating to solve your specific problem but I'd like to annotate: I've had the same problem and could solve it by removing 'by_reference' => false which was needless here and the reason for this error.

like image 28
Marc Juchli Avatar answered Nov 12 '22 20:11

Marc Juchli


Had the same problem and used pretty much the answer Daggah supposed, but added a small loop through the array of entities, checking for objects:

if ($this->get('session')->has('filters')) {
    $filters = $this->get('session')->get('filters');
    foreach ($filters as $key => $filter) {
        if (is_object($filter)) {
            $filters[$key] = $em->merge($filter);
        }
    }
    $filterForm = $this->createForm(new FilterType(), $filters);
}

Hope this helps someone.

like image 36
jahller Avatar answered Nov 12 '22 21:11

jahller