2015-12-03 3 views
25

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

Сначала я создаю новый проект 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 %} 

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

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

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

ответ

15

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

Как я уже упоминал выше, файл 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. Выражение в предложении, если выглядит следующим образом:

fields_mapping['tags']['type'] 

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

EDIT:

Я отправил вопрос на GitHub:

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

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

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

17

Похож на регресс после datetime fix в комплекте с генератором.

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

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

+0

Спасибо! Я просто пишу длинный ответ с результатами моих исследований. Мое решение немного отличается, но идея такая же. – cezar

3

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

 Смежные вопросы

  • Нет связанных вопросов^_^