自从几天前(2015年11月30日)发布Symfony的最后一个LTS版本以来,我开始玩它.不幸的是,我无法使用在Symfony 2.7.7中运行良好的相同代码的写操作生成CRUD.
首先,我使用bash
Linux 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版以来已更改.
看起来像生成器包中的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基于相同的假设掩盖了更多隐藏的错误.
我正在研究一下,并试图调试错误.
如上所述,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