Создание форм с помощью Symfony 2.8 приводит к тому, что Twig_Error_Runtime

Поскольку последняя версия LTS Symfony была выпущена несколько дней назад (30.11.2015), я начал играть с ней. К сожалению, я не могу генерировать CRUD с действиями записи с тем же кодом, который отлично работает в Symfony 2.7.7.

Сначала я создаю новый проект Symfony, используя bash под Linux Mint 17.2:

 symfony new tasks lts 

Новые tasks каталога создаются с новым проектом Symfony 2.8.0 внутри.

После адаптации учетных данных базы данных в app/config/parameters.yml я создаю базу данных:

 app/console doctrine:database:create 

и создать новый пакет:

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

Затем я создаю новый каталог src/Acme/TasksBundle/Resources/config/doctrine и размещаю два файла для своих моделей внутри. Эти:

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 

Схема базы данных должна выглядеть так:

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

Теперь я могу сгенерировать объекты:

 app/console generate:doctrine:entities AcmeTasksBundle 

Это отлично работает, поэтому база данных может быть обновлена:

 app/console doctrine:schema:update --force 

Все хорошо до сих пор. Таблицы находятся в базе данных. Теперь я хочу генерировать CRUD с действиями записи:

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

После подтверждения нескольких вопросов он генерирует CRUD и распечатывает:

 Generating the CRUD code: OK 

и затем выдает эту ошибку:

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

Контроллер создается, но не форма.

Генерация CRUD без параметров записи работает нормально. Тот же самый код работает безупречно с Symfony 2.7.7.

Я проверил различия в form/FormType.php.twig файла form/FormType.php.twig между версиями, и вот некоторые из них:

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

Как я вижу, условие if в цикле for – это место, где происходит ошибка. (Я предполагаю, что выражение fields_mapping[field]['type'] вызывает проблему, поскольку многое поле ( tag ) не имеет type атрибута.)

Что я делаю неправильно? Как я могу решить эту проблему? Большое спасибо за Вашу помощь.

EDIT: та же проблема возникает с Symfony 3.0.0. Форма файла form/FormType.php.twig была изменена с версии 2.8.

    Похож на регрессию после фиксации даты и времени в комплекте генератора.

    Быстрое решение – вернуться к v2. * В вашем composer.json :

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

    Лучшим решением является разветвление репо, исправление ошибки и создание запроса на перенос, чтобы внести свой вклад в сообщество.

    Поскольку вы уже выполнили всю работу, чтобы изолировать ошибку, исправление тривиально: проверьте, существует ли type в Resources/skeleton/form/FormType.php.twig . Что-то вроде

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

    если ошибка не маскирует более скрытые ошибки, основанные на том же предположении.

    Я немного разбирался и пытался отладить ошибку.

    Как я уже упоминал выше, form/FormType.php.twig файла form/FormType.php.twig была изменена с версии 2.8.0.

    Очевидно, производители Symfony хотели улучшить формы и автоматически разрешать типы date , time и datetime . Это происходит в строке:

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

    Это должно быть достигнуто с помощью массива fields_mapping .

    С помощью некоторых быстрых и грязных обходных решений я попытался выяснить, что скрывается внутри fields_mapping . Это результат для моей модели:

    задача

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

    При повторении через поля задачи на последнем шаге он проходит через tags полей. Выражение в предложении if выглядит следующим образом:

     fields_mapping['tags']['type'] 

    Как мы видим в предыдущем примере, в fields_mapping для Task нет ключевых tags , только id и description . Поскольку ключевые tags не существуют, возникает ошибка.

    Я изменил соответствующую строку в файле form/FormType.php.twig чтобы выглядеть так:

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

    Теперь мы можем использовать новую функцию, и мы предотвращаем ошибку, проверяя, существует ли ключ в массиве.

    Я не знаю, является ли это ошибкой или что-то не так в моем конкретном случае. Сейчас уже через неделю после выпуска версий 2.8.0 и 3.0.0, поэтому, вероятно, многие тысячи пользователей играли с ними. Я не мог поверить, что если это ошибка, никто бы этого не заметил.

    РЕДАКТИРОВАТЬ:

    Я опубликовал вопрос о GitHub:

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

    Это была ошибка, которая была решена так же, как я думал и писал выше:

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

    Даже если после обновления фиксированного пакета проблема все еще существует, иногда самый простой способ решить проблему – удалить каталог vendor и обновить композитор.