【发布时间】:2018-07-20 19:23:49
【问题描述】:
简介
所以,我有一个实体 Presence 被 Doctrine 监视。
我还有另一个实体 Decision 不受 Doctrine 关注。
Presence实体有一个属性$decisions,类型为ArrayCollection,包含0到n个Decision实体。
由于我不存储 ArrayCollection 中包含的每个 Decision 对象,我将属性 $decision 键入为 Doctrine Array,到目前为止一切正常。
我可以从数据库中取回整个 Presence 对象,它包含我添加到其中的每个 Decision 对象。
问题
当我编辑 Presence 对象的 ArrayCollection 中存在的一个 Decision 对象时,例如:
foreach($Presence->getDecisions() as $decision) {
$decision->setMorning($value);
}
修改是在本地应用的,我可以在做dump($Presence);时看到它们
Presence {#2354 ▼
#id: 8
#decisions: ArrayCollection {#1409 ▼
-elements: array:6 [▼
0 => Decision {#1408 ▼
#token_id: "005867b2915438c03383bb831d87c26346c586d6ecd46b735c7a23b4fabb682a8ac34a90ea3d53cc55c2209deaa83337abeb2b98ded43967fcfb0f4d04d5ada6"
#date: DateTime @1531692000 {#1407 ▶}
#morning: -1
#afternoon: 0
}
1 => Decision {#1406 ▶}
2 => Decision {#1404 ▶}
3 => Decision {#1402 ▶}
4 => Decision {#1400 ▶}
5 => Decision {#1398 ▶}
]
}
#last_edit_date: DateTime @1532109183 {#2454 ▼
date: 2018-07-20 19:53:03.062940 Europe/Berlin (+02:00)
}
#user: User {#1393 ▶}
}
在这个dump() 上,你可以看到属性#morning: -1 是setter 调用的结果。
但是当我尝试用$this->entityManager->flush(); 刷新更改时,ArrayCollection 没有被修改。
起初我认为这是更改检测的问题,所以我在我的 Presence 实体中添加了一个#last_edit_date DateTime 字段。
有趣的是,这个属性在刷新时更新得很好。
ArrayCollection 似乎由于某种原因不会更新。
更新
为了完成我的帖子,这里有更多信息:
控制器中的完整方法
/**
* @Route(name="edit_decision", path="/edit-decision/{tokenDate}/{dayPart}/{newValue}")
*/
public function EditDecisionAction(Request $request)
{
$token = $request->get('tokenDate');
$dayPart = $request->get('dayPart');
$newValue = intval($request->get('newValue'));
$myPresence = $this->em->getRepository('AppBundle:Presence')->findOneBy([
'user' => $this->connectedUser
]);
/** @var ArrayCollection $decisionCollection */
$decisionCollection = $myPresence->getDecisions();
$found = FALSE;
/** @var Decision $decision */
foreach ($decisionCollection as $decision) {
if ($decision->getTokenId() == $token) {
$found = TRUE;
if ($dayPart === 'morning') {
$decision->setMorning($newValue);
}elseif ($dayPart === 'afternoon') {
$decision->setAfternoon($newValue);
}
break;
}
}
if (!$found) {
throw $this->createNotFoundException();
}
// I set a new Date to trigger a modification on the Presence Entity : It works
$myPresence->setLastEditDate(new \DateTime());
// Here is the dump that you can see above
dump($myPresence);
$this->em->flush();
try{
$this->em->flush();
return $this->json([
'status' => TRUE
]);
}catch (\Exception $exception) {
return $this->json([
'status' => FALSE
]);
}
}
包含 ArrayCollection 的属性:
/**
* Doctrine Type Array
*
* @ORM\Column(type="array", nullable=true)
*/
protected $decisions;
欢迎任何帮助甚至提示! 谢谢:)
更新 2
感谢这篇文章,我可能已经找到了解决方案:
How to force Doctrine to update array type fields?
问题来自我存储对象的原则数组类型:
Doctrine 使用相同的运算符 (===) 来比较新旧值之间的变化。在具有不同数据的同一对象(或对象数组)上使用的运算符始终返回 true。还有另一种方法可以解决这个问题,你可以克隆一个需要更改的对象。
更新 3
Nope 仍然不会保留对数据库中 ArrayCollection 的项目所做的更改。 将尝试克隆:添加:删除旧的,我们将看看会发生什么。
【问题讨论】:
-
控制器中的完整功能比转储更好。你能完成你的答案吗?还要添加渲染表单的树枝视图部分,以及您在控制器中使用的
FormType -
你可能需要使用 on-flush: $unitOfWork->recomputeSingleEntityChangeSet($classMetadata, $entity) 或者你需要使用 pre-update: doctrine-project.org/projects/doctrine-orm/en/latest/reference/…
-
添加你的控制器和树枝
标签: php symfony doctrine-orm symfony-3.4