簡體   English   中英

如何過濾實體關系以返回主對象,而不返回相關對象? (Symfony2 / Doctrine2)

[英]How can I filter Entity relationships to return the main object, but not the related one? (Symfony2/Doctrine2)

我正在嘗試在Symfony2中實現軟刪除功能。 我想要的大多數東西都在工作,但是我在與相關實體的聯系上遇到了一些麻煩。 對於非關鍵數據,我希望能夠軟刪除相關的實體,但仍將所有數據保留在原位。

例如,假設我有一個帳戶實體和一個城市實體,其表結構如下:

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

因此,在這種情況下,“ Phoenix”已被軟刪除,並且帳戶表中的兩行都保留了該鏈接。 這樣,可以取消刪除Phoenix,並且不會丟失數據。

但是,顯然,如果Phoenix已被軟刪除,那么在查看“帳戶”時,我不想顯示該數據。 我創建了一個Doctrine過濾器,它將過濾出deleted = 1行。 但是,由於“帳戶”表中的鏈接列仍然存在,因此從本質上講,它指向不存在的相關對象(鳳凰),從而引發EntityNotFoundException。

這是我的問題。 在保留兩個對象之間的鏈接的同時,如何仍顯示帶有軟刪除的城市的帳戶列表?

在我看來,查看帳戶列表時,應顯示以下內容:

Account Name | City
---------------------------
Jane Doe     | -
John Smith   | -
Dave Jones   | New York

作為一項快速實驗,我嘗試捕獲EntityNotFoundException並僅返回數據。 這似乎可以按我的預期工作,但它確實是一個丑陋的hack,必須在各處重復進行(除非有我不知道的另一種方式)。 這是我測試過的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';
    }
}

提前致謝!

這是教義2的一個已知限制,該限制在不久前就已報道

不幸的是, 官方建議不要使用這種模式,而是將delete標志作為業務邏輯進行管理,如下所示:

class Employee
{
    // ...
    private $manager; // soft-deleted to-one association
    public function getManager()
    {
        return $this->manager && $this->manager->active() ? $manager : null;
    }
}

class Manager
{
    // ...
    private $deleted; // soft-delete flag, mapped as datetime|null
    public function active()
    {
        return ! $this->deleted;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM