所以我有一个包含一个包含另一个集合的集合的表单,两个集合都有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);
}
}
}
}
}
答案 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(当然,如果你需要的话)