当前位置:  开发笔记 > 编程语言 > 正文

使用Symfony 2.8生成表单会抛出Twig_Error_Runtime

如何解决《使用Symfony2.8生成表单会抛出Twig_Error_Runtime》经验,为你挑选了2个好方法。

自从几天前(2015年11月30日)发布Symfony的最后一个LTS版本以来,我开始玩它.不幸的是,我无法使用在Symfony 2.7.7中运行良好的相同代码的写操作生成CRUD.

首先,我使用bashLinux Mint 17.2 创建一个新的Symfony项目:

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

一切都还好,直到现在.这些表位于数据库中.现在我想用write动作生成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 %}

我看到for循环中的if条件是发生错误的地方.(我假设表达式fields_mapping[field]['type']导致问题,因为多对多的field(tag)没有属性type.)

我做错了什么?我怎么解决这个问题?非常感谢您的帮助.

编辑:Symfony 3.0.0出现同样的问题.该文件form/FormType.php.twig自2.8版以来已更改.



1> Alex Blex..:

看起来像生成器包中的datetime fix之后的回归.

快速解决方案是在您的composer.json:中恢复为v2.*

"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'] %}

除非该bug基于相同的假设掩盖了更多隐藏的错误.



2> cezar..:

我正在研究一下,并试图调试错误.

如上所述,form/FormType.php.twig自2.8.0版本以来,该文件已被更改.

显然,Symfony的厂商想提高的形式和自动解决的类型date,timedatetime.这发生在行中:

{%- 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']

正如我们在前面的例子中看到,有没有关键tagsfields_mapping任务,只有iddescription.由于密钥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

推荐阅读
勤奋的瞌睡猪_715
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有