symfony4 - 如何创建可以根据实体当前状态拒绝的自定义更新操作?
问题描述
我正在创建一个自定义PUT
操作。
不使用内置操作,因为受影响的属性不包含在该实体的默认规范化中,并且还因为该操作有一些超出该实体/模型的副作用。
此外,只有当数据库上实体的当前状态符合某些预期时,更新操作才会成功。
例如对于实体
class Lead {
/**
* @ORM\Column(type="integer", nullable=true)
* @Groups({"lead", "leadReject" })
**/
private $rejectionReason
public function isRejected() {
return $this->rejectionReason !== null;
}
我正在创建自定义操作PUT /lead/{id}/reject
。
class LeadReject {
public function __invoke( Lead $data ): Lead {
// if lead is rejected, we need not only to update its status
// but create an entry in a LeadLog table, and update the state
// for the Lead owner
}
}
问题是,当我们到达时__invoke()
,$data
我已经将用户的输入与数据库中的值合并了。因此,任何对的调用$data->isRejected()
都会返回 true,即使它仍在null
数据库中。
在我持久化对象并执行所有其他操作之前,我需要检查Lead
之前没有被拒绝。
我怎样才能做到这一点?可以在操作控制器级别完成吗?我想我可以注入 EntityManager 并再次检索对象,但考虑到此时对象已经被检索到,这似乎很浪费。
解决方案
你可以添加一个 Doctrine Listener:
<?php
namespace App\Listener;
use App\Entity\MyEntity;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
class EntityPreUpdateListener
{
/**
* @param MyEntity $entity
* @param LifecycleEventArgs $args
*/
public function preUpdate($entity, LifecycleEventArgs $args)
{
$entityManager = $args->getObjectManager();
// do whatever you need
// you can persist your entity to the database if you need
$entityManager->flush();
// detach your entity, so it won't be updated
$entityManager->detach($entity);
}
}
只需在您的实体 Doc Block 中添加这一行
@ORM\EntityListeners({"App\Listener\EntityPreUpdateListener"})
您可以在此处查看有关教义事件的更多信息:
https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/events.html
推荐阅读
- python - 扩展一个类而不访问其 __init__ 方法
- javascript - ReferenceError: algoliasearch 未定义
- laravel - 扩展文件夹中缺少 postgresql uuid-ossp.control 文件。我在 Windows 10 上安装了 postgres 9.6
- c++ - Boost.Python 与多处理兼容吗?
- python - 在python中对json文件进行排序
- php - 如何避免 PHP 自动将 int 转换为 float
- excel - Excel在大量列上连接
- python - 使用 forloop 覆盖列表中的项目
- java - Elasticsearch + Spring Boot - 以驼峰形式声明的字段返回为 null / 0
- flask - 会话不可用,因为未设置密钥