symfonyapi-platform.comdoctrine-extensions

Use Extension to filter OneToMany relationship


I'm using API Platform 3 and Gedmo's Softdeleteable Extension. For my entities, I'm using Extensions to add $queryBuilder->andWhere('o.deletedAt IS NULL') to all queries.

This is working fine, but when using OneToMany relations, API Platform doesn't use these extensions and therefor shows 'softdeleted' entities.

Let's take a slightly modified example from their documentation:

#[ApiResource]
class User
{
    #[ORM\OneToMany] 
    #[Serializer\Groups(['user'])]
    public Collection $offers;
}

/api/offers/1 correctly shows a 404, because it has been softdeleted. But /api/users/1 shows something like this:

{
    username: 'foo',
    offers:
    {
        '@id': "/api/offers/1",
        deletedAt: "2022-01-27T12:04:45+01:00"
    }
}

How can I change the query that API Platform uses to fetch the relationships?


Solution

  • You have two methods of achieving this.

    1. Filter hydrated objects:

    Inside the existing (or completely new) getter:

    return $this->offers->filter(function(Offer offer){
       return $offer->getDeletedAt() !== NULL;
    });
    
    1. Apply criteria to query:

    Again, inside the existing (or completely new) getter:

    $criteria = Criteria::create()
                ->andWhere(Criteria::expr()->eq('deletedAt', NULL));
    
    return $this->offers->matching($criteria);
    

    The Criteria method is preferable if your user could have LOTS of deleted offers - the filtering would be performed on a database level.

    Hope this helps.

    Btw, both of these methods are well explained in SymfonyCasts tutorials: