Symfony2单向多人集合表格



我被卡住了:-)

也许我只是在研究中使用了错误的关键词。但我没打通。所以我希望有一个人能帮助我!

我有一个单向的ManyToMany协会。当我试图提交表单(因此坚持)时,我得到了错误:

通过关系"TrainerInInInPool\AppBundle\entity\Trainer#applicationFields"找到了一个新实体,该实体未配置为级联实体的持久化操作:TrainerIninPool\AppBundle\entity\ApplicationField@0000000022ef36c600000000087bcbc3.

当我进行"级联持久化"时,会创建一个实际上已经存在的新实体。

我有两个实体:

  • 培训师
  • 应用程序字段

培训师与ApplicationField有一个单向的ManyToMany关联:

class Trainer {
public function __construct()
{
$this->applicationFields = new ArrayCollection();
}
[...]
/**
* @ORMManyToMany(targetEntity="ApplicationField")
*/
protected $applicationFields;

ApplicationField有一个自引用的OneToMany关联:

class ApplicationField {
public function __construct() {
$this->children = new ArrayCollection();
}
[...]
/**
* @ORMOneToMany(targetEntity="ApplicationField", mappedBy="parent")
*/
private $children;
/**
* @ORMManyToOne(targetEntity="ApplicationField", inversedBy="children")
* @ORMJoinColumn(name="parent_id", referencedColumnName="id")
*/
private $parent;

我想创建一个表单,在其中我可以添加一个Trainer-ApplicationField关联。

因此,我有一个ApplicationFieldCollectionType:

class ApplicationFieldCollectionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('applicationFields', 'collection', array(
'type'         => new ApplicationFieldType(),
'allow_add'    => true,
'label' => false
))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'TrainerInnenPoolAppBundleEntityTrainer',
));
}

嵌入类型如下:

class ApplicationFieldType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('applicationFieldName', 'entity', array(
'class' => 'TrainerInnenPoolAppBundle:ApplicationField',
'label' => false,
'mapped' => false,
'property' => 'name',
'query_builder' => function(EntityRepository $repository) {
return $repository->createQueryBuilder('application_field')
->where('application_field.parent is NULL');
}
)); 
$builder->add('name', 'entity', array(
'class' => 'TrainerInnenPoolAppBundle:ApplicationField',
'label' => false,
'property' => 'name',
'query_builder' => function(EntityRepository $repository) {
return $repository->createQueryBuilder('application_field')
->where('application_field.parent = 1');
}
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'TrainerInnenPoolAppBundleEntityApplicationField',
));
}

最后缺失的部分:控制器:

public function editApplicationField($id, Request $request)
{
$entityManager = $this->getDoctrine()->getEntityManager();
$trainer = $entityManager->getRepository('TrainerInnenPoolAppBundle:Trainer')->find($id);
$editForm = $this->createForm(new ApplicationFieldCollectionType(), $trainer);
if ($request->getMethod() == 'POST') {
$editForm->handleRequest($request);
$entityManager->flush();
}

当我从Trainer获取ApplicationField实体并尝试持久化这些实体时,

$editForm->handleRequest($request);
$af = $trainer->getApplicationFields();
foreach ($af as $applicationField) {
$trainer->addApplicationField($applicationField);
$entityManager->persist($applicationField);
}
$entityManager->flush();

我不能这样做,因为我得到了一个"密钥PRIMARY的重复条目"-异常。

我想我没有抓住任何明显的要点。如果有人能帮助我,给我一个提示,或者只是提到用信息更新我的问题,我会非常感激。

亲切问候。。。

您的嵌套类型setter由于缺少属性而未被调用:

->add('applicationFields', 'collection', array(
'type'         => new ApplicationFieldType(),
...
'by_reference' => false
...

http://symfony.com/doc/current/reference/forms/types/collection.html#by-参考

当您计划具有可添加/可删除的集合字段("allow_add"、"allow_delete")时,应始终提供"by_reference"=>false选项,以便直接在相关实体上调用setter,然后建立关联,而不是从原始实体中建立链方法。

希望这能有所帮助!

您需要cascade={"persistent"}注释,因为您希望将整个实体及其与ApplicationField的关联持久化。如果不使用cascade={"persistent"},则必须手动持久化实体。

实体已经添加到训练器中,所以如果你想手动持久化实体,你应该删除行

$trainer->addApplicationField($applicationField);

并且仅执行持久化。

这应该行得通。试试吧。但我认为效果会和你使用级联持久化的效果一样。所以我认为这不是最终的解决方案,而是理解问题的第一步,为什么手册以前不起作用。

相关内容

  • 没有找到相关文章

最新更新