سؤال

SETUP:

  • Main entity with a related entity with ManyToOne relation.
  • Main entity has a formType with the related entity added.
  • The related entity is a big object with a lot of fields and related objects, and very slow to get.
public function buildForm(FormBuilderInterface $builder, array $options)
{
  $builder
      ->add('relatedEntity', 'entity', array(
          'class' => 'ProjectName\RelatedEntityBundle\Entity\RelatedEntity',
          'query_builder' => function (EntityRepository $er) {
                  $queryBuilder = $er->createQueryBuilder('relatedEntity');
                  $queryBuilder->resetDQLPart('select');
                  $queryBuilder->resetDQLPart('from');
                  $queryBuilder->select('relatedEntity')
                      ->distinct(true)
                      ->from('ProjectNameRelatedEntityBundle:RelatedEntity', 'relatedEntity');
                  return $queryBuilder;
              },
       ....
       ....
}


Template:
(relateEntity has a __toString() function defined to show its name).

{{ form_label(form.relatedEntity) }}
{{ form_widget(form.relatedEntity) }}
{{ form_errors(form.relatedEntity) }}


QUESTIONS:

  1. The Main entity as shown above, will get all objects and pass them to the template. It works perfectly but it is very slow since the related entity objects are big and the query may take more 10 seconds to finish hydrating all the object data.
  2. How could I select only some fields from my related entity and show them in the template without getting all objects hydrated?
  3. Is it possible to use the choice option or another type instead of the default entity type to get only some fields of the related entity and show them in the template?
  4. How could I build a custom query hydrated as a simple array of key value, and pass that array to the formType, to the queryBuilder of my related entity field?
  5. Finally, in case its not possible to get only some fields to be shown in the template, should I avoid symfony 2 forms and make a custom management of the related entity?



TESTS:
I cant seem to build the form with the choice type by passing just an array to show a selectBox with the id and name of my related entity in the template. I always get the same error, asking me to insert an array of entity objects in that choiceS option.

Lets look at some examples at the formType, buildForm function of the main entity:

  • WORKS, default Symfony 2 generated code with null type:

->add('relatedEntity', null, array('label'=> 'relatedEntity'))


  • WORKS, with 'entity' type and a simple queryBuilder:
->add('relatedEntity', 'entity', array(
  'class' => 'ProjectName\RelatedEntityBundle\Entity\RelatedEntity',
  'query_builder' => function (EntityRepository $er) {
          $queryBuilder = $er->createQueryBuilder('relatedEntity');
          $queryBuilder->resetDQLPart('select');
          $queryBuilder->resetDQLPart('from');
          $queryBuilder->select('relatedEntity')
              ->from('ProjectNameRelatedEntityBundle:RelatedEntity', 'relatedEntity');
          return $queryBuilder;
      },
  'property' => 'descripcion'
))


  • DOESNT WORK with 'choice' type, with 'choices' option passing an array of values:

$arrayValues = array('1'=>'name1', '2'=>'name2', '3'=>'name3');

    ->add('relatedEntity', 'choice', array(
        'choices' => $arrayValues,
        'multiple' => false,
        'label'=> 'relatedEntity'
    ))


  • DOESNT WORK with 'entity' type, with 'choices' option passing an array of values:

$arrayValues = array('1'=>'name1', '2'=>'name2', '3'=>'name3');

    ->add('relatedEntity', 'entity', array(
        'class' => 'ProjectName\RelatedEntityBundle\Entity\RelatedEntity',
        'choices' => $arrayValues ,
        'multiple' => false,
        'label'=> 'relatedEntity'
    ))


I have also tested trying to hack the choices input requeriment by building an array of objets of my related entity, but it asks me to persists those entities before being sent to the choice type.

هل كانت مفيدة؟

المحلول

The problem is your form element which requires its content to be an entity, which is an instance of class ProjectName\RelatedEntityBundle\Entity\RelatedEntity, but you pass an array as choices:

$arrayValues = array(
    '1'=>'name1',
    '2'=>'name2',
    '3'=>'name3'
);

On the other hand, when you use a choice-element and add the array, your form element will return a string, whereas your entity requires relatedEntity to be an instance of the above mentioned class.

Either way, you have to ensure the data you add or retrieve from the element matches your requirements.

What you can do, is make it a choice-element and remove the class-restriction (as you have tried). Then, to ensure it will return an entity-instance rather than a string you can use Form Events. You could use FormEvents::SUBMIT or FormEvents::PRE_SUBMIT to check which entity name was selected and perform a query to fetch the corresponding entity, e.g. something like:

$objectRepository->findEntityBy(array('name' => $name));
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top