Home > Enterprise >  Symfony and Doctrine ORM fetchAll with condition of column
Symfony and Doctrine ORM fetchAll with condition of column

Time:09-19

I'm using Symfony 6.1 and Doctrine, and i have 2 entities:

<?php

namespace App\Entity;

use App\Repository\UserRepository;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
#[ORM\Entity(repositoryClass: UserRepository::class)]
class User
{
    #[ORM\Id, ORM\GeneratedValue, ORM\Column]
    private ?int $id = null;

    #[ORM\ManyToMany(targetEntity: Account::class, inversedBy : 'users')]
    #[ORM\OrderBy(["isDefaultAccount" => "DESC"])]
    private Collection $accounts;

    public function getId(): ?int
    {
        return $this->id;
    }
}

and

<?php

namespace App\Entity;

use App\Repository\AccountRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Entity(repositoryClass: AccountRepository::class)]
#[ORM\HasLifecycleCallbacks]
class Account
{
    #[ORM\Id, ORM\GeneratedValue, ORM\Column]
    private ?int $id = null;

    #[ORM\ManyToMany(targetEntity: User::class, mappedBy: "accounts", orphanRemoval: true)]
    private Collection $users;

    #[ORM\Column]
    private bool $isActive = false;

    public function __construct()
    {
        $this->users = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    /**
     * @return Collection<int, UserInterface>
     */
    public function getUsers(): Collection
    {
        return $this->users;
    }

    public function addUser(UserInterface $user): self
    {
        if (!$this->users->contains($user)) {
            $this->users[] = $user;
            $user->addAccount($this);
        }

        return $this;
    }

    public function removeUser(UserInterface $user): self
    {
        if ($this->users->removeElement($user)) {
            $user->removeAccount($this);
        }

        return $this;
    }

    public function getIsActive(): bool
    {
        return $this->isActive;
    }

    public function setIsActive(bool $isActive): self
    {
        $this->isActive = $isActive;

        return $this;
    }
}

In my controler, i want when i do:

$user->getAccounts();

i wnat this return only accounts where isActive === true.

And when i do :

$accountRepository->fetchAll();

I want this return all accounts only with isActive === true.

I know we can do:

$accountRepository->findBy(['isActive' => true]);

I want when i always when i fetch account only return isActive === true, accounts isActive === false never came up.

But i think i can do it with an attribute. Can someone help me please?

CodePudding user response:

You can use matching() on your accounts collection to filter out only relevant ones. If I remember correctly, Doctrine will even try to load only the affected rows on relationships when possible, instead of applying the filter afterwards.

If you always want to have this restriction, it might make sense to use filters in the ORM to always ensure that only active accounts are fetched.

CodePudding user response:

I used this on my User entity:

/**
 * @return Collection<int, Account>
 */
public function getAccounts(): Collection
{
    $criteria = Criteria::create()
        ->andWhere(Criteria::expr()->eq('isActive', true))
        ->orderBy(['isDefaultAccount' => Criteria::DESC])
        ->orderBy(['id' => Criteria::ASC]);
    return $this->accounts->matching($criteria);
}

Thank you @dbrumann

  • Related