php doctrine symfony symfony-2.8

php - La generación de formularios con Symfony 2.8 arroja Twig_Error_Runtime



doctrine symfony-2.8 (3)

Desde que se lanzó la última versión LTS de Symfony hace unos días (30.11.2015) comencé a jugar con ella. Desafortunadamente no puedo generar un CRUD con acciones de escritura con el mismo código que funciona bien en Symfony 2.7.7.

Primero creo un nuevo proyecto de Symfony usando bash en Linux Mint 17.2:

symfony new tasks lts

Las nuevas tasks directorio se crean con un nuevo proyecto Symfony 2.8.0 dentro.

Después de adaptar las credenciales de la base de datos en app/config/parameters.yml creo la base de datos:

app/console doctrine:database:create

y generar un nuevo paquete:

app/console generate:bundle --namespace=Acme/TasksBundle --format=yml

Luego creo un nuevo directorio src/Acme/TasksBundle/Resources/config/doctrine y src/Acme/TasksBundle/Resources/config/doctrine dos archivos para mis modelos dentro. Estos son:

Task.orm.yml

Acme/TasksBundle/Entity/Task: type: entity repositoryClass: Acme/TasksBundle/Repository/TaskRepository table: task id: id: type: integer generator: { strategy : AUTO } fields: description: type: text manyToMany: tags: targetEntity: Tag inversedBy: tasks cascade: [ "persist" ] joinTable: name: task_tag joinColumns: task_id: referencedColumnName: id inverseJoinColumns: tag_id: referencedColumnName: id

Tag.orm.yml

Acme/TasksBundle/Entity/Tag: type: entity repositoryClass: Acme/TasksBundle/Repository/TagRepository table: tag id: id: type: integer generator: { strategy : AUTO } fields: name: type: string length: 50 manyToMany: tasks: targetEntity: Task mappedBy: tags

El esquema de la base de datos debería tener esto:

+----------------+ +--------------+ | task | | task_tag | +---------+ +----------------+ +--------------+ | tag | | id |<--->| task_id | +---------+ | description | | tag_id |<--->| id | +----------------+ +--------------+ | name | +---------+

Ahora puedo generar las entidades:

app/console generate:doctrine:entities AcmeTasksBundle

Esto funciona bien, por lo que la base de datos se puede actualizar:

app/console doctrine:schema:update --force

Todo está bien hasta ahora. Las tablas están en la base de datos. Ahora quiero generar CRUD con acciones de escritura:

app/console generate:doctrine:crud --entity=AcmeTasksBundle:Task --with-write --format=yml

Después de confirmar algunas preguntas, genera el CRUD e imprime:

Generating the CRUD code: OK

y luego arroja este error:

[Twig_Error_Runtime] Key "tags" for array with keys "id, description" does not exist in "form/FormType.php.twig" at line 29

El controlador se crea, pero no la forma.

Generar el CRUD sin opciones de escritura funciona bien. El mismo código funciona sin problemas con Symfony 2.7.7.

form/FormType.php.twig las diferencias en el form/FormType.php.twig archivo form/FormType.php.twig entre las versiones y aquí están las partes relevantes:

Symfony 2.7.7
vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/form/FormType.php.twig

{%- if fields|length > 0 %} /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder {%- for field in fields %} ->add(''{{ field }}'') {%- endfor %} ; } {% endif %}

Symfony 2.8.0
vendor/sensio/generator-bundle/Resources/skeleton/form/FormType.php.twig

{%- if fields|length > 0 %} /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder {%- for field in fields -%} {%- if fields_mapping[field][''type''] in [''date'', ''time'', ''datetime''] %} ->add(''{{ field }}'', ''{{ fields_mapping[field][''type''] }}'') {%- else %} ->add(''{{ field }}'') {%- endif -%} {%- endfor %} ; } {% endif %}

Como veo la condición if en el ciclo for es el lugar donde ocurre el error. (Supongo que la expresión fields_mapping[field][''type''] causa el problema, ya que el campo many to many ( tag ) no tiene ningún type atributo).

¿Que estoy haciendo mal? ¿Como puedó resolver esté problema? Muchas gracias por su ayuda.

EDITAR: El mismo problema ocurre con Symfony 3.0.0. El archivo form/FormType.php.twig ha sido cambiado desde la versión 2.8.


Estuve investigando un poco e intenté depurar el error.

Como mencioné anteriormente, el archivo form/FormType.php.twig ha sido cambiado desde la versión 2.8.0.

Obviamente, los fabricantes de Symfony querían mejorar los formularios y resolver automáticamente los tipos de date , time y datetime y datetime . Esto sucede en la línea:

{%- if fields_mapping[field][''type''] in [''date'', ''time'', ''datetime''] %}

Esto se debe lograr con la ayuda de la matriz fields_mapping .

Con algunas soluciones rápidas y sucias intenté descubrir qué hay escondido dentro de fields_mapping . Este es el resultado de mi modelo:

Tarea

{ id => { id => 1, fieldName => id, type => integer, columnName => id }, description => { fieldName => description, type => text, columnName => description } }

Al recorrer los campos de Tarea, en el último paso pasa por las tags campo. La expresión en la cláusula if se ve así:

fields_mapping[''tags''][''type'']

Como vemos en el ejemplo anterior, no hay tags clave en fields_mapping para Task, solo id y description . Como las tags clave no existen, se genera el error.

Cambié la línea en cuestión en el form/FormType.php.twig archivo form/FormType.php.twig para que se vea así:

{%- if fields_mapping[field] is defined and fields_mapping[field][''type''] in [''date'', ''time'', ''datetime''] %}

Ahora podemos usar la nueva característica y evitamos un error comprobando si la clave existe en la matriz.

No sé si esto es un error o hay algo mal en mi caso particular. Ahora ya es una semana desde el lanzamiento de las versiones 2.8.0 y 3.0.0, por lo que probablemente miles de usuarios hayan estado jugando con ellos. No podía creer eso, si es un error, nadie se habría dado cuenta de esto.

EDITAR:

Publiqué un problema en GitHub:

https://github.com/sensiolabs/SensioGeneratorBundle/issues/443

Este fue un error, que se ha resuelto de la misma manera, como pensé y escribí arriba:

https://github.com/Maff-/SensioGeneratorBundle/commit/205f64e96a94759f795271cb00fc86fb03b1fd4a


Incluso si después de actualizar el paquete fijo, el problema sigue existiendo, a veces la forma más fácil de resolver el problema es eliminar el catálogo del vendor y actualizar el compositor.


Parece una regresión después del arreglo de fecha y hora en el paquete del generador.

Una solución rápida es volver a v2. * En su composer.json :

"sensio/generator-bundle": "^2.5",

La mejor solución es bifurcar el repositorio, arreglar el error y crear una solicitud de extracción para contribuir a la comunidad.

Como ya hiciste todo el trabajo para aislar el error, la solución es trivial: comprueba si existe el type en Resources/skeleton/form/FormType.php.twig . Algo como

{%- if fields_mapping[field][''type''] is defined and fields_mapping[field][''type''] in [''date'', ''time'', ''datetime''] %}

a menos que el error enmascare más errores ocultos basados ​​en la misma suposición.