Doctrine + Symfony2:Forms:从另一个集合中包含的集合中删除已删除的元素

时间:2014-03-19 04:56:46

标签: php symfony doctrine-orm

所以我有一个包含一个包含另一个集合的集合的表单,两个集合都有allow_add& allow_delete设置为true。但是当我从子集合中删除一些项目时我遇到了问题。我正在关注Symfony2文档,为简单起见,我将使用http://symfony.com/doc/current/cookbook/form/form_collections.html中的相同文档示例

class Task
{
    protected $description;

    protected $tags;

    ....
}


class Tag
{
    protected $name;

    protected $categories;

     ....
}



class Category
{
    protected $name;

    ....
}

现在用户更新表单后,我必须通过比较原始Collection和新的Collection来确保数据库持久性。来自Symfony2文档:

$originalTags = new ArrayCollection();
// Create an ArrayCollection of the current Tag objects in the database
foreach ($task->getTags() as $tag) {
    $originalTags->add($tag);
} 

此处Tags按值复制,而Categories中的tags仍然会被引用复制,一旦用户从$originalTags中删除的表单中删除了一个

我解决了这个问题,但它变得非常复杂,我确信这种方法不是最好的,所以我正在寻找更好的方法


其他信息

我尝试在类__clone上实现Tag,如下所示:

Tag中的

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);
               }
            }
        }
     }
 }

1 个答案:

答案 0 :(得分:1)

为什么不尝试使用

之类的东西
$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
}

但是,我们必须验证一些事情,因为如果你clone a" doctrine"对象,entity manager可以"丢失"它的参考,并且不能再将它持久保存到db(当然,如果你需要的话)