Cualquiera que haya trabajado con Symfony y se haya visto en la necesidad de añadir un campo en un formulario que haga referencia a una entidad se habrá visto en la situación de que la única opción posible es usar el tipo 'entity'. Este tipo tienes dos grandes problemas:
- Solo permite mostrar el campo mediante checkboxes, radiobuttons o selects, donde todas las opciones posibles se muestran para que el usuario escoja alguna en concreto. Esto dificulta mucho la interacción en casos como el de recuperar una entidad vía AJAX y vincularla al formulario.
- La eficiencia de lo anterior es nula, porque obliga a recuperar todos los valores posibles de la entidad a la hora de mostrar el campo. Imagina que necesitas un campo usuario y tienes más de 5000 en tu base de datos. Sería inviable usar el tipo entity.
Este es un tema que lleva dando vueltas por los repositorios de Symfony desde hace 2 años. Una solución es la propuesta por el usuario Gregwar en este PR https://github.com/symfony/symfony/pull/1951/, que añade el tipo 'entity_id'. Del ejemplo de la misma página:
$builder->add('city', 'entity_id', array( 'query_builder' => function($repository, $id) { return $repository->createQueryBuilder('c') ->where('c.id = :id AND c.available = 1') ->setParameter('id', $id); }, 'class' => 'Gregwar\TestBundle\Entity\City', 'required' => false, 'hidden' => true ));
Con este tipo es posible tener un campo de texto o un campo oculto en el que poder insertar automáticamente el ID de una entidad, olvidándonos de selects, radiobuttons o checkboxes, y sin hacer prefetchs de las entidades. Yo llevo usándolo desde hace 8 meses y me ha resuelto bastantes problemas.
Aunque hay bastantes solicitudes para hacer oficial este PR, parece que finalmente la solución oficial va a ser la de añadir un atributo widget al tipo entity, como se detalla aquí https://github.com/symfony/symfony/issues/6602 :
I think that we should add two new options
I think that we should add two new options
widget
and delimiter
to ChoiceType.widget
can be one of the valuesselect
,checkbox
,radio
andtext
delimiter
can be any single character
Behavior:
widget = 'select'
: This is equivalent toexpanded = false
right now.widget = 'checkbox'
:multiple
must not be set to false. Otherwise equivalent toexpanded = true
.widget = 'radio'
:multiple
must not be set to true. Otherwise equivalent toexpanded = true
.widget = 'text'
: A text input is shown.- if
multiple
is false, the input must equal one of the predefined choices. - if
multiple
is true, the input is split by the character defined indelimiter
(a comma by default), then each value is trimmed (unlesstrim
is false). Each resulting input must equal one of the predefined choices.
- if
Solución bastante más genérica y limpia, y que incluye el tipo de widget text, que combinado con el atributo multiple soluciona el problema de poder referenciar entidades "manualmente". Lo que no aclara esta solución es si seguirá haciendo prefetch o no de todas las entidades posibles. A día de hoy este debate sigue abierto en Github.
4 comentarios:
Hola, puedes mostrar un ejemplo o pequeño tutorial, de su uso ? ... del uso de este bundle? . te lo agardeceria bastante, ya que yo recupero 11 entidades distintas y algunas tiene mas de 1000 registros, con esto se utiliza el autocomplete de jqeury? -- muchas gracias y saludos
Hola Fernando,
¿A qué tipo de tutorial te refieres? Si te refieres al uso del tipo entity_id junto con el autocomplete de jQuery, la clave está en que usando ese tipo vas a tener un campo de tipo texto que después se vinculará con una entidad. A ese campo de tipo texto le puedes dar funcionalidad de autocomplete indicámdpñe una fuente que te devuelva en JSON el id y el texto que quieras usar como value y label respectivamente. Si me das más detalles te intento echar una mano.
HOla, gracias por tu respuesta, eso mismo que dices hice, solo que usando otro método .... de igual forma alguna duda que tenga sobre algun tema mencionado aqui, te contactare. de antemano muchas gracias........
Publicar un comentario