Search code examples
phpsymfonydoctrineentityarraycollection

How can I retrieve data from ArrayCollection (Symfony)?


animals:

| id | name |
|----|------|
| 1  | cat  |
| 2  | dog  |
| 3  | frog |

category:

| id | name   |
|----|--------|
| 1  | green  |
| 2  | blue   |
| 3  | orange |

animals_category:

| animals_id | category_id |
|------------|-------------|
| 1          | 1           |
| 2          | 1           |
| 2          | 2           |

What I want to do is get the categories for dog:

green, blue

This is my approach:

Controller:

$id = '2';

$result = $this->getDoctrine()->getRepository('Animals:Category')->findByIdJoinedToCategory(['id'=>$id]);

Animals Repository:

   public function findByIdJoinedToCategory()
    {
        $query = $this->getEntityManager()
            ->createQuery(
                'SELECT a, b FROM Animals:Category a
                JOIN a.category b');
        try {
            return $query->getResult();
        } catch (\Doctrine\ORM\NoResultException $e) {
            return null;
        }
    }

But I get an error message:

Unknown Entity namespace alias 'Animals'.

entity Animals:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
* @ORM\Entity(repositoryClass="App\Repository\AnimalsRepository")
*/
class Animals
{
  /**
  * @ORM\Id()
  * @ORM\GeneratedValue()
  * @ORM\Column(type="integer")
  */
  private $id;


  /**
  * @ORM\Column(type="string", length=255)
  */

  private $name;


  /**
  * @ORM\ManyToMany(targetEntity="Category")
  * @ORM\JoinColumn(name="category", referencedColumnName="id")
  */
  private $category;




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


  public function getName()
  {
    return $this->name;
  }

  public function setName($name)
  {
    $this->name = $name;
  }


  public function getCategory()
  {
    return $this->category;
  }

  public function setCategory($category): self
  {
    $this->category = $category;

    return $this;
  }

  public function addCategory(Category $category): self
  {
    $this->category[] = $category;

    return $this;
  }

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

Solution

  • There's no Animals:Category entity. You have entities Animals and Category.

    The correct answer depends if you're using Symfony 3 or 4, because Symfony 3 uses entity aliases (namespacing with : notation which you're trying ot use), while Symfony 4 prefers full qualified namespace (\App\Entity\Animals).

    So, first mistake is in line where you're trying to get repository:

    getRepository('Animals:Category')
    

    And the second in findByIdJoinedToCategory() in DQL query :

    'SELECT a, b FROM Animals:Category a
    JOIN a.category b'
    

    Now solutions:

    Symfony 3

    Since it looks you don't have any bundles (I guess it's Symfony 4 but whatever), you don't have any entity namespace alias, so you should simply use its name.

    getRepository('Animals')
    

    Now, I assume, that with a you want to reference Animals entity/table, so it should be

    'SELECT a, b FROM Animals a
    JOIN a.category b'
    

    Symfony 4

    If you use Symfony 4, then use should use entity FQNS as entity name (App\Entity\Animals).

    So it would be

    getRepository('\App\Entity\Animals')
    

    or

    getRepository(\App\Entity\Animals::class)
    

    to get repository. The second one is better, because it will be easier to refactor when needed (IDE will be able to find usage of class).

    And in query it would be

    'SELECT a, b FROM App\Entity\Animals a
    JOIN a.category b'
    

    or if you would like to avoid using hardcoded string class names:

    'SELECT a, b FROM ' . \App\Entity\Animals:class . ' a
    JOIN a.category b'