Symfony形式:如何在Doctrine实体中包含一个表格,用于实体本身使用的可嵌入学说

时间:2016-01-23 10:42:02

标签: symfony doctrine-orm doctrine symfony-forms value-objects

我有一个使用Doctrine embeddable的学说Entity

我想创建一个表单来修改EntityEmbeddable

我的Entity

/**
 * MyEntity
 *
 * @ORM\Table(name="my_entities")
 * @ORM\Entity(repositoryClass="\AppBundle\Entity\MyEntityRepository")
 * @ORM\HasLifecycleCallbacks
 */
class MyEntity
{
    ...

    /**
     * @var MyEmbeddableInfo
     *
     * @ORM\Embedded(class="AppBundle\Entity\Embeddable\MyInfoEmbeddable")
     */
    private $myInfo;

    ...

我的Embeddable

/**
 * @ORM\Embeddable
 */
class MyInfoEmbeddable
{
    /**
     * @var string
     *
     * @ORM\Column(name="info1", type="string", nullable=true)
     *
     * @Assert\NotBlank(groups={"setUp"})
     */
    private $info1;

    /**
     * @var string
     *
     * @ORM\Column(name="info2", type="string", nullable=true)
     *
     * @Assert\NotBlank(groups={"setUp"})
     */
    private $info2;

    /**
     * @var
     *
     * @ORM\Column(name="info3", type="string", nullable=true)
     *
     * @Assert\NotBlank(groups={"setUp"})
     */
    private $info3;

    ...

我做了什么

我发现这个question here on Stackoverflow并且似​​乎用户遇到了同样的问题,但区别在于我从未得到Warning,因为我根本不理解创建表单的基本过程可嵌入的对象。

我做了两个测试:一个直接将可嵌入对象传递给MyEntityType表单构建器,另一个创建MyInfoType()表单类型。

测试1:直接进入可嵌入对象

这是我MyEntityType班的代码:

class MyEntityType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ...
            ->add('myInfo', 'entity', ['class' => '\AppBundle\Entity\Embeddable\MyInfoEmbeddable'])
            ...
    }

    public function getName()
    {
        return 'MyEntity';
    }
}

此解决方案会抛出RuntimeException

  

班级\AppBundle\Entity\Embeddable\MyInfoEmbeddable似乎不是   托管的Doctrine实体。你忘了映射吗?

测试2:通过MyInfoType对象

我做的第二个测试是使用表单类型(如linked SO question中所示):

public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ...
            ->add('myInfo', new MyInfoType())
            ...
    }

这是MyInfoType的代码:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('infoField1', 'text', ['required' => false])
        ->add('infoField2', 'text', ['required' => false])
        ->add('infoField3', 'choice', [
                'choices'   => [
                    '' => '',
                    'choice1' => 'Choice 1',
                    'choice2' => 'Choice 2',
                    'choice3' => 'Choice 3'
                ],
                'required' => false
            ]
        );
}

而是返回Symfony\Component\PropertyAccess\Exception\NoSuchIndexException

  

无法从类型对象中读取索引infoField1   AppBundle\Entity\Embeddable\MyInfoEmbeddable因为它没有   实施\ArrayAccess

所以,这个解决方案也不起作用。

我的目标是为MyEntity创建一个表单,并在此表单中创建要更新MyInfoEmbeddable的字段。

要遵循哪个正确的程序?

2 个答案:

答案 0 :(得分:2)

而不是以主要形式:

$builder->add('myInfo', new MyInfoType(), 
['data_class' => '\AppBundle\Entity\Embeddable\MyInfoEmbeddable'])

您可以在MyInfoType表单中添加它(我相信,它与可嵌入实体链接):

public function configureOptions(OptionsResolver $resolver)
{
   $resolver->setDefaults([
      'data_class' => '\AppBundle\Entity\Embeddable\MyInfoEmbeddable',
   ]);
}

然后在您的主窗体中简单地调用可嵌入的表单类型,如下所示:

$builder->add('myInfo', new MyInfoType())

答案 1 :(得分:1)

在使用不同的keywords进行了一些其他搜索之后,我想出了this answer here on SO来帮助我解决问题。

我真的很接近解决方案。我只是省略了一个必需的参数来构建表单。

解决方案是将data_class参数传递给add()的{​​{1}}方法:

FormBuilder