Php 条令+;Symfony2:窗体:从包含在另一个集合中的集合中删除已删除的元素
因此,我有一个包含一个集合的表单,其中包含另一个集合,两个集合都将Php 条令+;Symfony2:窗体:从包含在另一个集合中的集合中删除已删除的元素,php,symfony,doctrine-orm,Php,Symfony,Doctrine Orm,因此,我有一个包含一个集合的表单,其中包含另一个集合,两个集合都将allow\u add和allow\u delete设置为true。但是我在从子集合中删除某些项目时遇到了一个问题。我遵循Symfony2文档,为了简单起见,我将使用来自的相同文档示例 现在,在用户更新表单之后,我必须通过比较原始集合和新集合来确保数据库的持久性。从Symfony2文档: $originalTags = new ArrayCollection(); // Create an ArrayCollection of t
allow\u add
和allow\u delete
设置为true
。但是我在从子集合中删除某些项目时遇到了一个问题。我遵循Symfony2文档,为了简单起见,我将使用来自的相同文档示例
现在,在用户更新表单之后,我必须通过比较原始集合和新集合来确保数据库的持久性。从Symfony2文档:
$originalTags = new ArrayCollection();
// Create an ArrayCollection of the current Tag objects in the database
foreach ($task->getTags() as $tag) {
$originalTags->add($tag);
}
这里,标记
按值复制,而标记
中的类别
仍按引用复制,并且一旦用户从表单中删除一个,它也从$originalTags
中删除
我解决了这个问题,但它变得相当复杂,我确信这种方法不是最好的,所以我正在寻找更好的方法
其他信息 我试图在类
标记上实现\u clone
,如下所示:
在标记中
:
public function __clone()
{
$this->categories = new ArrayCollection();
}
我将$originalTags
的创建方式更改为:
$originalTags = new ArrayCollection();
foreach ($task->getTags() as $tag) {
$cat_array = array();
$t = clone $tag;
foreach($tag->getCategories() as $category) {
$t->addCategory(clone $category);
}
$originalTags->add($t);
}
这就是我计算变更集并保存实体的方式:
foreach ($originalTags as $tag) {
if (false === $task->getTags()->exists(function ($key, $element) use ($tag) {if($element->getId() == $tag->getId() )return true; })) {
$temp = $entityManager->find('...\Tag', $tag->getId());
$entityManager->remove($temp);
} else {
foreach($task->getTags() as $t)
{
if($t->getId() == $tag->getId())
{
$originalTag = $t;
}
}
foreach ($tag->getCategories() as $category) {
if (false === $originalTag->getCategories()->exists(function ($key, $element) use ($category) {if($element->getId() == $category->getId() )return true;})) {
$temp = $entityManager->find('...\Category', $category->getId());
$entityManager->remove($temp);
}
}
}
}
}
你为什么不试试像这样的东西
$originalTags = new ArrayCollection();
// Create an ArrayCollection of the current Tag objects in the database
foreach ($task->getTags() as $tag) {
$cat_array = array();
foreach($tag->getCategories() as $categories) {
$cat_array[] = clone $categories;
}
$originalTags->addCategories($cat_array); //you have to write this method
}
但是,我们必须验证一些东西,因为如果您克隆了一个“条令”对象,实体管理器可能会“丢失”其引用,并且无法将其再次保存到db(当然,如果您需要的话)正在尝试类似的操作。似乎一旦克隆对象并比较原始对象和新的$category
失败,$tag->getCategories()->contains($category)
将始终返回false。当然,它将失败;它们不是同一个物体。。。我的意思是,你可以覆盖->contains()
操作,只比较实体id(或者主键,如果你愿意)并执行这个技巧,但是假设我克隆了一个类别
,那么条令就不能再管理它了,之后,用户删除该类别,这样它就不再存在于$tag->getCategories()中
因此,一旦我在原始类别和新类别之间进行比较,我会发现缺少的类别,因此我需要将其删除,但我无法将其从原始数组中删除,因为它是克隆的,也无法从其自身的对象中删除,因为它已被表单删除class@ra_htial:是的,我明白你的意思,但目前我帮不了你更多:(不用担心,非常感谢!
$originalTags = new ArrayCollection();
// Create an ArrayCollection of the current Tag objects in the database
foreach ($task->getTags() as $tag) {
$cat_array = array();
foreach($tag->getCategories() as $categories) {
$cat_array[] = clone $categories;
}
$originalTags->addCategories($cat_array); //you have to write this method
}