4

I'm new with symfony and I'm trying to view data from one of my tables with random order and a limit of 4. I tried doing it in the repository but RAND() is not working so I'm trying in the controller.

The error is the following one:

"Warning: array_rand() expects parameter 1 to be array, object given"

And I don't understand why, when in the $response I set the data into an array.

This is my actual code:

/**
* @Route("/ws/random/superviviente", name="ws_random_survi")
*/
    public function randomSurvi(Request $request): Response
    {
        $data = $request->request->all();
        $entityManager = $this->getDoctrine()->getManager();

        $randomPerks = $entityManager->getRepository(Perks::class)
            ->getRandomPerks();
        
        $response = new JsonResponse();
        $response -> setStatusCode(200);
        $response -> setData(array('random perk' => $randomPerks));

        $resultRandom = array_rand($response);

        return $resultRandom;
        
    }
bafecas538
  • 41
  • 1

2 Answers2

1

You are trying to use array_rand on a doctrine array collection.

You could either convert it as array and back to a doctrine array :

use Doctrine\Common\Collections\ArrayCollection;
public function randomSurvi(Request $request): Response
    {
        $data = $request->request->all();
        $entityManager = $this->getDoctrine()->getManager();

        $randomPerks = $entityManager->getRepository(Perks::class)
            ->getRandomPerks();
        
        $resultRandom = new ArrayCollection(array_rand($randomPerks->toArray()));

        return new JsonResponse($resultRandom);
        
    }

Otherwise it would work with shuffle :

 $randomPerks = $entityManager->getRepository(Perks::class)->getRandomPerks();
 $randomPerks = shuffle($randomPerks);

Or get random perks directly through your method in your repository.

See example from @Krzysztof Trzos:

  public function getRandomProducts($amount = 7)
    {
        return $this->getRandomProductsNativeQuery($amount)->getResult();
    }


/**
 * @param int $amount
 * @return ORM\NativeQuery
 */
public function getRandomProductsNativeQuery($amount = 7)
{
    # set entity name
    $table = $this->getClassMetadata()
        ->getTableName();

    # create rsm object
    $rsm = new ORM\Query\ResultSetMapping();
    $rsm->addEntityResult($this->getEntityName(), 'p');
    $rsm->addFieldResult('p', 'id', 'id');

    # make query
    return $this->getEntityManager()->createNativeQuery("
        SELECT p.id FROM {$table} p ORDER BY RAND() LIMIT 0, {$amount}
    ", $rsm);
}
Dylan KAS
  • 4,840
  • 2
  • 15
  • 33
  • with the first option this error appears: Attempted to call an undefined method named "toArray" of class "Symfony\Component\HttpFoundation\JsonResponse". – bafecas538 Mar 30 '21 at 12:13
  • My bad, used wrong variable, fixed it, other part on my answer should work tho – Dylan KAS Mar 30 '21 at 13:01
0

You could write your own query to achieve this, so create a new method inside the repository like so:

public function getRandomPerks(int $limit): array
{
    $queryBuilder = $this->createQueryBuilder('p');

    return $queryBuilder
        ->setMaxResults($limit)
        ->orderBy('RAND()')
        ->getQuery()
        ->getResult();
}

Then in your controller all you would to do is call the method and pass a limit:

$randomPerks = $entityManager->getRepository(Perks::class)
    ->getRandomPerks(4);
MylesK
  • 3,349
  • 2
  • 9
  • 31