Генерация форм с помощью 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 между версиями и здесь находятся соответствующие части:

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.)

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

РЕДАКТИРОВАТЬ:
Та же проблема возникает с Symfony 3.0.0. Файл form/FormType.php.twig был изменен с версии 2.8.

26

Решение

Похоже, регрессия после исправление даты и времени в генераторной связке.

Быстрое решение — вернуться к 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'] %}

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

17

Другие решения

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

Как я уже говорил выше, файл 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
}
}

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

fields_mapping['tags']['type']

Как мы видим в предыдущем примере, здесь нет ключа tags в fields_mapping только для задачи 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

17

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

3
По вопросам рекламы [email protected]