我有3个实体:资产,用户,日志
关系是:
所以场景是这样的:
我在资产实体上尝试过这样做:
public function addUser(\AppBundle\Entity\User $user)
{
$this->users[] = $user;
$this->getDoctrine()->getManager()->persist(new Log($this,
"Asset has been added to" . $user->getFullname()
,$this->getUser()));
$this->getDoctrine()->getManager()->flush();
return $this;
}
这给了我一个错误,即找不到EM,我做了一些研究,发现这是不好的做法。
所以我尝试了这个:
$oldAsset = $this->getDoctrine()->getManager()->getRepository('AppBundle:Asset')->findOneById($asset->getId());
if ($assign_form->isSubmitted() && $assign_form->isValid()) {
foreach($asset->getUsers() as $user)
if(!$oldAsset->getUsers()->contains($user))
$this->getDoctrine()->getManager()->persist(new Log($asset,
"Asset has been assigned to " . $user->getFullname()
,$this->getUser()));
foreach($oldAsset->getUsers() as $user)
if(!$asset->getUsers()->contains($user))
$this->getDoctrine()->getManager()->persist(new Log($asset,
"Asset has been removed from " . $user->getFullname()
,$this->getUser()));
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('asset_show', array('id' => $asset->getId()));
}
即使在我手动冲洗它之前,它还没有起作用,它会更新"来自数据库的实体,因此旧资产和新资产之间没有差异。奇怪的是,在整个方法完成之前,一旦出现错误,编辑就无法通过。
我知道我在这里遗漏了一些东西,也许有一种我不知道的方法会使这种情况成为可能。
答案 0 :(得分:2)
这可以通过事件监听器(Symfony doc,Doctrine doc)来实现:
<强>的Acme \监听\ UserListener.php:强>
<?php
namespace Acme\Listener;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\EntityManagerInterface;
use Acme\Entity;
class UserListener {
/**
* @ORM\PostUpdate()
*/
public function postUpdate(Entity\User $user, LifecycleEventArgs $event) {
$em = $event->getEntityManager();
$log = new Entity\Log(...);
// ...
$em->persist($log);
$em->flush();
}
}
将监听器注册为服务,标记为doctrine.event_listener
:
<强> services.yml:强>
services:
# ...
Acme\EventListener\UserListener:
arguments: [ '@doctrine.orm.entity_manager' ]
tags:
- { name: doctrine.event_listener }
现在,只要刷新了一个更改了由实体管理器管理的User
对象的操作,就应该调用监听器的postUpdate
方法。
对于下一位,我假设您已将User
配置为与Asset
的关系中的拥有方。
如果您正确设置了实体(意味着在更改关系时同步更新反面,可以在Doctrine docs和this gist中找到更多信息),则听众不仅应该在向/从用户分配/删除资产时调用,还要在向资产分配/从资产中删除用户时调用。