How to filter result of a query builder according condition on join?

Viewed 204

I created my query builder, with a join and a condition, but the returned result on the joined data is full and is not filtered according to my join condition (group.id = 3).

How to modify my query or entities to get the affiliations and groups filtered accordingly?

Thank you.

Query in repository

    $affiliationsGroup = 3;
    $query = $this->createQueryBuilder('u');
    $query->join('u.affiliations', 'a');
    $query->join('a.group', 'g');
    $query->andWhere('g.id = :group');
    $query->setParameter('group', $affiliationsGroup);
    $query->getQuery();

returned result

[
        {
            "id": 42,
            "name":"user42";
            "affiliations": [
                {
                    "id": 1,
                    "group": {
                        "id": 1,
                        "name": "group1",
                      }
                   
                },
                {
                    "id": 94,
                    "group": {
                        "id": 3,
                        "name": "group3"
                      
                    },
                   
                }
]

User Entity

 /**
     * @ORM\OneToMany(targetEntity=Affiliations::class, mappedBy="user", cascade={"persist"})
     * @Serializer\Groups({"student"})
     */
    private $affiliations;

Affiliation Entity

/**
     * @var \Users
     *
     * @ORM\ManyToOne(targetEntity="Users", inversedBy="affiliations", cascade={"persist"})
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     * })
     * @Serializer\Groups({"student"})
     */
    private $user;

/**
     * @var \Groups
     *
     * @ORM\ManyToOne(targetEntity="Groups", inversedBy="affiliations")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="group_id", referencedColumnName="id")
     * })
     * @Serializer\Groups({"public", "student"})
     */
    private $group;

Controller User

   /**
     *
     * Get all users
     *
     * @Rest\Get("/api/admin/users", name="get_users")
     * @Rest\View(serializerGroups={"student"})
     * @param Request $request
     * @return View
     */
    public function indexAction(Request $request): View
    {
            //Access repository and service to call function and my query builder
    }
1 Answers

While the results might not be as expected, there is nothing wrong with your code. It filters correctly.

To understand what's happening, you should understand the two steps:

  1. User 42 (I see what you did here) has at least 1 affiliation in group 3 so is part of the result.
  2. Your serializer will serialize the results. And since user 42 has two affiliations, it will serialize them as well.

Since the serializer doesn't know which filters are applied when querying the results, it doesn't apply those filters.

Unfortunately, this is how API Platform works: it doesn't filter nested entities. See this issue for more details/discussion. You can find some dirty tricks to change the behaviour, but when I encountered the same issue in my project, I decided to filter the nested entities in the front end instead.

Related