Sonata Admin Bundle 和 Doctrine 问题:如何从反面更新实体?
Posted
技术标签:
【中文标题】Sonata Admin Bundle 和 Doctrine 问题:如何从反面更新实体?【英文标题】:Sonata Admin Bundle and Doctrine issue: how to update an entity from inversed side? 【发布时间】:2012-09-03 11:55:47 【问题描述】:我有两个实体之间的多对多关系。我们称它们为User
和Group
。
我决定在创建/更新界面上,因为它们可以关联,您可以直接关联来自组表单的用户或来自用户表单的组。请注意,关系的拥有方是User
现在问题来了。如果我从用户表单界面关联组,一切都很好并且工作完美(教义寻找拥有方的变化)。如果我尝试从组表单界面关联User
,则没有任何效果。
显然我完全知道我必须将用户“添加”到组对象中,并将组 (this) 添加到我从表单传递的每个用户对象中。实际上这是我在Group
实体中的sn-p代码
public function setUsers(\Doctrine\Common\Collections\ArrayCollection $utente)
/* snippet of code for removing old association , didn't reported */
foreach($utente as $u)
$this->users[] = $u;
$u->addGroups($this);
从这个sn-p进入创造形式,做好他的工作。进入更新,它没有。 所以我想这一定是奏鸣曲的问题,或者是我目前错过的东西。
有什么建议吗?
更新
在花了一些时间了解这里发生了什么之后,我发现setUser()
没有被调用到更新操作中(读作提交构建在现有实体上的表单)。所以我的代码只有在我创建新条目时才会运行(我仍然没有解决方案)
【问题讨论】:
【参考方案1】:我刚刚了解了如何更新实体。 我想这是与 Symfony2 相关的行为,而不是 Sonata Admin 的行为。
简而言之,您必须告诉 Symfony2 调用您要更新的对象的 setter。
用于该用途:
by_reference => false
在 Sonata Admin Bundle 案例中:
$formMapper
->add('nome')
->add('canali', 'sonata_type_model', array('required' => false))
->add('utenti', 'sonata_type_model', array('required' => false,
'by_reference' => false))
;
在纯 Symfony2 形式的情况下:
->add('utenti', 'collection', array(
'type' => new User(),
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'by_reference' => false,
))
;
【讨论】:
【参考方案2】:不清楚你的意思是更新它不能很好地工作。根据您的代码,我假设它会在用户和组之间添加新的关系,但不会删除旧的。
public function setUsers(\Doctrine\Common\Collections\ArrayCollection $utente)
// to synch internal and external collections, remove relation between users and groups if user is not in the new collection
foreach ($this->users as $u)
if (!$utente->contains($u))
// add this function to user object, it's trivial, just remove give group from internal groups collection
$u->removeGroup($this);
foreach ($utente as $u)
if (!$this->users->contains($u))
$this->users[] = $u;
$u->addGroups($this);
【讨论】:
是的,我错过了仅添加新用户的控件。但是您完全错过了这个问题:setUsers 似乎不适用于更新操作【参考方案3】:尝试将以下内容添加到您的管理类
public function prePersist($group)
$group->setUsers($group->getUsers());
parent::prePersist($testQuestion);
public function preUpdate($group)
$group->setUsers($group->getUsers());
parent::preUpdate($testQuestion);
【讨论】:
以上是关于Sonata Admin Bundle 和 Doctrine 问题:如何从反面更新实体?的主要内容,如果未能解决你的问题,请参考以下文章
Sonata Media Bundle 与 Sonata Admin Bundle 3.0(或 2.4)
sonata-project/user-bundle dev-master 与 sonata-project/doctrine-orm-admin-bundle 冲突