我有一个包含一个集合的表单,其中包含另一个集合,两个集合都有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;
....
}
现在在用户更新表单之后,我必须通过比较原始集合和新集合来确保数据库的持久性。来自Symfony2文档:
$originalTags = new ArrayCollection();
// Create an ArrayCollection of the current Tag objects in the database
foreach ($task->getTags() as $tag) {
$originalTags->add($tag);
}
这里的Tags
按值复制,而tags
中的Categories
仍然按引用复制,一旦用户从表单中删除一个,它也从$originalTags
中删除。
我解决了这个问题,但它变得非常复杂,我确信这种方法不是最好的,所以我正在寻找更好的方法
<
附加信息/strong>
我试图实现__clone
类Tag
像这样:
in Tag
:
public function __clone()
{
$this->categories = new ArrayCollection();
}
和i改变了$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
}
我们必须验证一些东西,然而,因为如果你clone
一个"原则"对象,entity manager
可能会"丢失"它的引用,并且无法再次将其持久化到db(当然,如果你需要的话)