Доктрина отношения "многие ко многим": не удалось автоматически получить данные из базы данных

В моем коде Symfony я использовал Doctrine. В Entity (AppBundle \ Entity \ Core \ User) я определил столбец foodTypes, который связан с другим Entity (AppBundle \ Entity \ FoodRecording \ FoodType). Я определил отношение «многие ко многим» между пользователем и FoodType с помощью таблицы ссылок foodrecording_user, присоединяющейся к User.username и FoodType.foodtype_code. Код показан ниже.

// Entity\Core\User
namespace AppBundle\Entity\Core;
......
class User implements AdvancedUserInterface, \Serializable {
......
/**
 * @ORM\ManyToMany(targetEntity = "AppBundle\Entity\FoodRecording\FoodType")
 * @ORM\JoinTable(name = "foodrecording_user",
 *      joinColumns = {@ORM\JoinColumn(name = "username", referencedColumnName = "username", onDelete = "CASCADE")},
 *      inverseJoinColumns = {@ORM\JoinColumn(name = "foodtype_code", referencedColumnName = "code", onDelete = "CASCADE")}
 *      )
 */
private $foodTypes;

public function getFoodTypes()
{
    $this->foodTypes = new \Doctrine\Common\Collections\ArrayCollection();

    return $this->foodTypes;
}

Однако, поскольку я хотел напрямую получить все типы еды определенного пользователя, используя

$userFoodTypes = $this->get('security.token_storage')->getToken()->getUser()->getFoodTypes();

тогда я получил

$userFoodTypes =====> array[]

Я ожидал, что, когда я создал отношение M-M, Doctrine автоматически извлечет нужные мне данные, но это не так!

Поэтому мне нужно написать свой собственный код для извлечения данных из БД / таблицы, как показано ниже:

public function fetchUserFoodTypes()
{
    global $kernel;
    $container = $kernel->getContainer();
    $em = $container->get('doctrine.orm.entity_manager');
    $conn = $em->getConnection();

    $sql = 'SELECT * FROM foodrecording_user where username = :username';
    $stmt = $conn->prepare($sql);
        $stmt->execute([
            'username' => $this->getUsername(),
        ]);

    $data = $stmt->fetchAll();

    $res = [];
    foreach ($data as $item) {

        $foodtype = $em->getRepository('AppBundle\Entity\FoodRecording\FoodType')->findByCode($item['foodtype_code']);
        $res[] = $foodtype;
    }

    return $res;
}

public function getFoodTypes()
{
    $this->foodTypes = $this->fetchUserFoodTypes();
    //$this->foodTypes = new \Doctrine\Common\Collections\ArrayCollection();

    return $this->foodTypes;
}

Только так я могу получить типы еды, связанные с пользователем.

Может ли кто-нибудь объяснить мне, почему я не могу просто использовать определение M-M и позволить доктрине делать все автоматически за меня? Почему я должен явно писать собственную функцию для извлечения данных из БД? Разве Доктрина недостаточно умна?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
0
0
33
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Эта часть: $this->foodTypes = new \Doctrine\Common\Collections\ArrayCollection(); Принадлежит к методу __construct, а не к геттеру. Как видите, каждый раз, когда вы вызываете геттер, вы сбрасываете свойство foodTypes на пустой экземпляр ArrayCollection.

Другие вопросы по теме