You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让API Platform 3在一对多关联中应用软删除扩展?

解决API Platform 3关联查询未应用Gedmo软删除过滤的问题

方法一:在Doctrine关联映射中直接添加过滤条件

最直接的方式是在实体的关联注解里加上@ORM\Where,让Doctrine在加载关联数据时自动过滤已软删除的记录。

比如在User实体的offers关联上:

// src/Entity/User.php
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class User
{
    // ... 其他字段

    /**
     * @ORM\OneToMany(targetEntity=Offer::class, mappedBy="user")
     * @ORM\Where(clause="deleted_at IS NULL")
     */
    private $offers;

    // ... getter/setter
}

这个方式属于Doctrine层面的全局过滤,不管是API Platform查询还是其他地方调用关联,都会自动排除已软删除的Offer实体。

方法二:自定义API Platform查询扩展,覆盖子资源查询

如果不想修改实体映射,或者需要更灵活的控制,可以自定义一个支持上下文的查询扩展,确保关联查询(子资源)也应用软删除过滤:

  1. 创建扩展类:
// src/Doctrine/Orm/Extension/SoftDeleteableExtension.php
use ApiPlatform\Doctrine\Orm\Extension\ContextAwareQueryExtensionInterface;
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use ApiPlatform\Metadata\Operation;
use Doctrine\ORM\QueryBuilder;
use Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter;

class SoftDeleteableExtension implements ContextAwareQueryExtensionInterface
{
    public function __construct(private readonly SoftDeleteableFilter $softDeleteableFilter)
    {
    }

    public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, Operation $operation = null, array $context = []): void
    {
        $this->applySoftDeleteFilter($queryBuilder, $resourceClass);
    }

    public function applyToItem(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, array $identifiers, Operation $operation = null, array $context = []): void
    {
        $this->applySoftDeleteFilter($queryBuilder, $resourceClass);
    }

    private function applySoftDeleteFilter(QueryBuilder $queryBuilder, string $resourceClass): void
    {
        $rootAlias = $queryBuilder->getRootAliases()[0];
        $this->softDeleteableFilter->addFilterConstraint($rootAlias, $resourceClass, $queryBuilder);
    }
}
  1. 注册服务(如果使用Symfony的autoconfigure可自动注册,否则在services.yaml配置):
# config/services.yaml
services:
    App\Doctrine\Orm\Extension\SoftDeleteableExtension:
        arguments: ['@gedmo.filter.softdeleteable']
        tags:
            - { name: api_platform.doctrine.orm.query_extension, priority: 10 }

设置优先级为10,确保它在其他默认扩展之前执行,保证过滤条件被正确添加。

方法三:启用Gedmo的Doctrine过滤器

确保Gedmo的SoftDeleteable过滤器已经在Doctrine配置中启用,这样Doctrine会自动为所有查询(包括关联查询)添加软删除过滤:

# config/packages/doctrine.yaml
doctrine:
    orm:
        filters:
            softdeleteable:
                class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter
                enabled: true

这个方式是全局启用,所有Doctrine查询都会自动排除已软删除的实体,包括API Platform的关联查询。若有特殊场景需要查询已删除实体,可临时禁用过滤器。


内容的提问来源于stack exchange,提问作者Stephan Vierkant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 12:43:28