Доктрина отношения многие ко многим: не удалось автоматически получить данные из базы данных - PullRequest
0 голосов
/ 30 июня 2018

В моем коде Symfony я использовал Doctrine. В сущности (AppBundle \ Entity \ Core \ User) я определил столбец foodTypes, который связан с другой сущностью (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;
}

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

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

1 Ответ

0 голосов
/ 01 июля 2018

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

...