【问题标题】:How to POST nested entities with FOSRest and Symfony Form如何使用 FOSRest 和 Symfony 表单发布嵌套实体
【发布时间】:2017-09-24 17:17:16
【问题描述】:

使用 Symfony 3.2 和 FOS REST Bundle 我已经为资源创建了一些 REST 端点,并使用 Symfony 表单来定义 API DOC 的字段。到目前为止一切正常。 现在我正在尝试改进我的架构并向我的资源添加一个子实体(一对一)。我希望主资源保存子实体 - 子实体没有专用端点。

我按照the Symfony documentation 上的说明删除了所有其他字段以隔离任何问题。

这就是我的表单类型现在的样子:

<?php

namespace VendorName\MyBundle\Form;

use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class CountryType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder
            ->add('mySubEntity', EntityType::class, array(
                'multiple' => false,
                'expanded' => false,
                'property' => 'name',
                'class' => 'MyBundle\Entity\mySubEntity'));
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'VendorName\MyBundle\Entity\Country',
            'csrf_protection' => false
        ));
    }

}

现在,当我加载我的 api-docs 时,我收到了错误消息 The option "property" does not exist. Defined options are: "action", "allow_extra_fields", [...]

老实说,我什至不知道将实体添加到表单是否是使其显示在 API 文档中的正确方法。任何帮助解决上述问题和/或实现这一目标的最佳实践将不胜感激。

编辑:感谢@miikes,此错误现已解决,我可以看到 api 文档正确显示嵌套表单的字段。但是,现在我的问题是表单没有填充父实体上的子实体。这似乎和我建模父子关系的方式有关,我发了new question for this issue

【问题讨论】:

    标签: php rest symfony fosrestbundle


    【解决方案1】:

    要解决您的错误,请尝试使用choice_label,而不是property 选项。

    'choice_label' =&gt; 'name'

    但是参考文档,EntityType is a kind of ChoiceType,所以使用这种类型,你只能选择现有的实体,不能持久化新的。

    创建新实体实例最简单、最清晰的方法是创建另一个为您的实体设计的类型类,并将该类型作为字段添加到您的 CountryType

    class MyEntityType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('some-field', TextType::class)
                ->add('another-field', TextType::class);
        }
    
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults([
                'data_class' => MyEntity::class
            ]);
        }
    }
    
    class CountryType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder->add('mySubEntity', MyEntityType::class);
        }
    
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => Country::class,
                'csrf_protection' => false
            ));
        }
    }
    

    所以你应该将表单数据传递为

    ['mySubEntity']['some-field'] = 'foo'
    ['mySubEntity']['another-field'] = 'bar'
    

    另一个技巧是使用Country::class 而不是字符串'VendorName\MyBundle\Entity\Country',因为在重命名类的情况下,IDE 重构会影响您的类型。

    【讨论】:

    • 太棒了!这就像一个魅力 - 创建一个子实体类型是要走的路。谢谢你:)
    猜你喜欢
    • 1970-01-01
    • 2014-08-25
    • 2019-06-14
    • 1970-01-01
    • 2018-07-06
    • 2016-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多