Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating forms with Symfony 2.8 throws a Twig_Error_Runtime

Since the last LTS version of Symfony was released few days ago (30.11.2015) I started playing with it. Unfortunately I can't generate a CRUD with write actions with the same code that works fine in Symfony 2.7.7.

First I create a new Symfony project using the bash under Linux Mint 17.2:

symfony new tasks lts 

The new directory tasks gets created with a new Symfony 2.8.0 project inside.

After adapting the database credentials in app/config/parameters.yml I create the database:

app/console doctrine:database:create 

and generate a new bundle:

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

Then I create a new directory src/Acme/TasksBundle/Resources/config/doctrine and place two files for my models inside. These are:

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 

The database schema should like this:

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

Now I can generate the entities:

app/console generate:doctrine:entities AcmeTasksBundle 

This works fine, so the database can be updated:

app/console doctrine:schema:update --force 

Everything ok till now. The tables are in the database. Now I want to generate CRUD with write actions:

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

After confirming few questions it generates the CRUD and prints out:

Generating the CRUD code: OK 

and afterwards throws this error:

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

The controller gets created, but not the form.

Generating the CRUD without write options works fine. The very same code works flawlessly with Symfony 2.7.7.

I checked the differences in the file form/FormType.php.twig between the versions and here are the relevant parts:

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 %} 

As I see the if condition in the for loop is the place where the error occurs. (I assume that the expression fields_mapping[field]['type'] causes the problem since the many to many field (tag) has no attribute type.)

What I am doing wrong? How can I solve this problem? Thank you very much for your help.

EDIT: The same problem occurs with Symfony 3.0.0. The file form/FormType.php.twig has been changed since version 2.8.

like image 592
cezar Avatar asked Dec 03 '15 12:12

cezar


1 Answers

Looks like a regression after datetime fix in the generator bundle.

A quick solution is to revert to v2.* in your composer.json:

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

The best solution is to fork the repo, fix the bug and create a pull request to contribute back to the community.

Since you already did all the job to isolate the bug, the fix is trivial: check if type exists in Resources/skeleton/form/FormType.php.twig. Something like

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

unless the bug masks more hidden errors based on the same assumption.

like image 160
Alex Blex Avatar answered Sep 21 '22 06:09

Alex Blex