我正在尝试在 Symfony2 中实现软删除功能。它主要按我的意愿工作,但是我在相关实体方面遇到了一些麻烦。对于非关键数据,我希望能够软删除相关实体,但仍保留所有数据。
例如,假设我有一个 Account Entity 和一个 City Entity,其表结构如下:
table: account
---------------------------
id | account_name | city_id
---------------------------
1 | Jane Doe | 1
2 | John Smith | 1
3 | Dave Jones | 2
table: city
---------------------------
id | city_name | deleted
---------------------------
1 | Phoenix | 1
2 | New York | 0
所以在这种情况下,“凤凰”已经被软删除了,account 表中的两行都保留了那个链接。这样就可以取消删除 Phoenix 并且不会丢失数据。
显然,如果 Phoenix 已被软删除,我不想在查看帐户时显示该数据。我创建了一个 Doctrine 过滤器,它将过滤掉deleted = 1
. 但是,由于 Account 表中的链接列仍然存在,本质上是指向了一个不存在的相关对象(Phoenix),因此抛出了 EntityNotFoundException。
这是我的问题。在保留两个对象之间的链接的同时,如何仍然显示具有软删除城市的帐户列表?
在我看来,在查看帐户列表时,应该会产生如下结果:
Account Name | City
---------------------------
Jane Doe | -
John Smith | -
Dave Jones | New York
作为一个快速实验,我尝试捕获 EntityNotFoundException 并返回数据。这似乎按我的意图工作,但它是一个相当丑陋的黑客,必须在整个地方重复(除非有另一种我不知道的方式)。这是我测试的 SonataAdmin CRUDController 的一个示例:
try {
return $this->render($this->admin->getTemplate('list'), array(
'action' => 'list',
'form' => $formView,
'datagrid' => $datagrid
));
} catch (\Twig_Error_Runtime $e) {
if (strpos($e->getMessage(), 'Entity was not found')) {
return $this->render($this->admin->getTemplate('list'), array(
'action' => 'list',
'form' => $formView,
'datagrid' => $datagrid
));
}
}
我对那个解决方案不满意;我觉得我错过了一种更好的方法。
作为记录,这是我的过滤器:
class SoftDeleteFilter extends SQLFilter
{
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
{
if (!$targetEntity->hasField('deleted')) {
return '';
}
return $targetTableAlias . '.deleted = false';
}
}
提前致谢!