Symfony 表单:如何在 Doctrine 实体中包含实体本身使用的可嵌入 Doctrine 的表单
Symfony forms: how to include in the Doctrine entity form a form for a Doctrine embeddable used by the entity itself
我有一个使用 Doctrine embeddable
的学说 Entity
。
我想创建一个表单来编辑 Entity
和 Embeddable
。
我的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 Whosebug 似乎用户遇到了我同样的问题,但不同的是我从来没有得到 Warning
因为我根本不了解创建可嵌入对象的形式。
我进行了两项测试:一项是将可嵌入对象直接传递给 MyEntityType
表单生成器,一项是创建 MyInfoType()
表单类型。
测试 1:直接传递可嵌入对象
这是我的代码 MyEntityType
class:
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
:
Class \AppBundle\Entity\Embeddable\MyInfoEmbeddable
seems not to be
a managed Doctrine entity. Did you forget to map it?
测试 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
]
);
}
这个 returns Symfony\Component\PropertyAccess\Exception\NoSuchIndexException
:
Cannot read index infoField1
from object of type
AppBundle\Entity\Embeddable\MyInfoEmbeddable
because it doesn't
implement \ArrayAccess
.
所以,这个解决方案也行不通。
我的目标是为 MyEntity
创建一个表单,并在该表单中创建要更新的字段 MyInfoEmbeddable
。
正确的步骤是什么?
在使用不同 keywords
进行了一些其他搜索后,我想出了 this answer here on SO 帮助我解决了问题。
我真的很接近解决方案。我只是省略了构建表单所需的参数。
解决方法是将data_class
参数传递给FormBuilder
的add()
方法:
...
$builder
->add('myInfo', new MyInfoType(), ['data_class' => '\AppBundle\Entity\Embeddable\MyInfoEmbeddable'])
...
而不是在你的主表单中这样:
$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())
我有一个使用 Doctrine embeddable
的学说 Entity
。
我想创建一个表单来编辑 Entity
和 Embeddable
。
我的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 Whosebug 似乎用户遇到了我同样的问题,但不同的是我从来没有得到 Warning
因为我根本不了解创建可嵌入对象的形式。
我进行了两项测试:一项是将可嵌入对象直接传递给 MyEntityType
表单生成器,一项是创建 MyInfoType()
表单类型。
测试 1:直接传递可嵌入对象
这是我的代码 MyEntityType
class:
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
:
Class
\AppBundle\Entity\Embeddable\MyInfoEmbeddable
seems not to be a managed Doctrine entity. Did you forget to map it?
测试 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
]
);
}
这个 returns Symfony\Component\PropertyAccess\Exception\NoSuchIndexException
:
Cannot read index
infoField1
from object of typeAppBundle\Entity\Embeddable\MyInfoEmbeddable
because it doesn't implement\ArrayAccess
.
所以,这个解决方案也行不通。
我的目标是为 MyEntity
创建一个表单,并在该表单中创建要更新的字段 MyInfoEmbeddable
。
正确的步骤是什么?
在使用不同 keywords
进行了一些其他搜索后,我想出了 this answer here on SO 帮助我解决了问题。
我真的很接近解决方案。我只是省略了构建表单所需的参数。
解决方法是将data_class
参数传递给FormBuilder
的add()
方法:
...
$builder
->add('myInfo', new MyInfoType(), ['data_class' => '\AppBundle\Entity\Embeddable\MyInfoEmbeddable'])
...
而不是在你的主表单中这样:
$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())