【问题标题】:Symfony forms: how to include in the Doctrine entity form a form for a Doctrine embeddable used by the entity itselfSymfony 表单:如何在 Doctrine 实体表单中包含实体本身使用的 Doctrine 可嵌入表单
【发布时间】:2016-04-29 23:34:07
【问题描述】:

我有一个使用 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:直接通过可嵌入对象

这是我MyEntityTypeclass的代码:

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 的字段。

要遵循的正确程序是什么?

【问题讨论】:

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


    【解决方案1】:

    在你的主要形式中代替这个:

    $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())
    

    【讨论】:

    • $builder->add($builder->create('myInfo', MyInfoType::class));
    【解决方案2】:

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

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

    解决方法是将data_class参数传递给FormBuilderadd()方法:

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

    【讨论】:

    • 我知道,这是一个品味问题,但我建议将“data_class”属性从主表单中调用的字段移动到可嵌入表单的 configureOptions 方法。
    • 你能写一个答案来澄清你的意思吗?
    猜你喜欢
    • 1970-01-01
    • 2014-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-04
    相关资源
    最近更新 更多