dev.elop
dev.elop

Reputation: 43

Symfony- passing an array of ids

I wrote an api with a function that sets notification as read by passing it's id.

But also, there should be an option to pass array of ids there, to mark several at once as read. I should extend function so that it handles the case where $this>data['id'] is an array.

Is this the right way?

My Service:

 public function read($id = []){

 $notification = $this->getRepository()->findBy([
        'id' => $id
    ]);

    if($notification) {
       $notification[0]->setRead(new \DateTime());
       $this->em->flush();
    }
}

My Controller:

public function readAction()
{
    $this->requirePostParams(['id']);
    $this->get('app')->read(
        $this->data['id']
    );

    return $this->success();
}

Upvotes: 4

Views: 2665

Answers (1)

Darragh Enright
Darragh Enright

Reputation: 14146

You can indeed pass an array of id values to \Doctrine\ORM\EntityRepository::findBy(); e.g:

$notifications = $this->getRepository()->findBy([
    'id' => [1, 2, 3] // etc.
]);

However, since findBy() can return multiple results, it will return an array (or array-like object like Doctrine\ORM\PersistentCollection). Therefore you should iterate over your result set:

foreach ($notifications as $notification) {
    $notification->setRead(new \DateTime());
}

$this->em->flush();

Additionally, it's a matter of taste to some degree but you may want to make your API more explicit and create separate methods for a single action versus a group action; e.g:

public function read(int $id)
{
    //in this scenario you are searching for one notification
    // only so you can use `findOneBy()` instead
    $notification = $this->getRepository()->findOneBy(['id' => $id]);
    $notification->setRead(new \DateTime());
    $this->em->flush();
}

public function readMany(array $ids)
{
    $notification = $this->getRepository()->findBy(['id' => $ids]);

    foreach ($notifications as $notification) {
        $notification->setRead(new \DateTime());
    }

    $this->em->flush();
}

As pointed out by @Yoshi, read() could also be neatly implemented as:

public function read(int $id)
{
    $this->readMany([$id]);
}

Hope this helps :)

Upvotes: 4

Related Questions