Symfony 4 Doctrine 2 findby dosent apply Присоединиться и пользовательское объединение не работает - PullRequest
2 голосов
/ 29 января 2020

Я относительно новичок с Symfony 4 и Doctrine ORM. Я пытаюсь получить все комментарии от одного пользователя при просмотре этой страницы профиля пользователя.

Вот моя сущность комментария

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

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

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Users", inversedBy="comments")
     * @ORM\JoinColumn(nullable=false)
     */
    private $auteur;

    /**
     * @ORM\Column(type="datetime")
     */
    private $postedAt;

    /**
     * @ORM\Column(type="text")
     */
    private $content;

    /**
     * @ORM\Column(type="integer", options={"default" : 0})
     */
    private $flagged;

    /**
     * @ORM\Column(type="boolean", options={"default" : 0})
     */
    private $validated;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Cards", inversedBy="comments")
     * @ORM\JoinColumn(referencedColumnName="card_id")
     */
    private $postedOnCard;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Users", inversedBy="commentsOnUser")
     */
    private $postedOnUser;

    /**
     * @ORM\Column(type="boolean", options={"default" : 0})
     */
    private $deleted;

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

    public function getAuteur(): ?users
    {
        return $this->auteur;
    }

    public function setAuteur(?users $auteur): self
    {
        $this->auteur = $auteur;

        return $this;
    }

    public function getPostedAt(): ?\DateTimeInterface
    {
        return $this->postedAt;
    }

    public function setPostedAt(\DateTimeInterface $postedAt): self
    {
        $this->postedAt = $postedAt;

        return $this;
    }

    public function getContent(): ?string
    {
        return $this->content;
    }

    public function setContent(string $content): self
    {
        $this->content = $content;

        return $this;
    }

    public function getFlagged(): ?int
    {
        return $this->flagged;
    }

    public function setFlagged(int $flagged): self
    {
        $this->flagged = $flagged;

        return $this;
    }

    public function getValidated(): ?bool
    {
        return $this->validated;
    }

    public function setValidated(bool $validated): self
    {
        $this->validated = $validated;

        return $this;
    }

    public function getPostedOnCard(): ?cards
    {
        return $this->postedOnCard;
    }

    public function setPostedOnCard(?cards $postedOnCard): self
    {
        $this->postedOnCard = $postedOnCard;

        return $this;
    }

    public function getPostedOnUser(): ?users
    {
        return $this->postedOnUser;
    }

    public function setPostedOnUser(?users $postedOnUser): self
    {
        $this->postedOnUser = $postedOnUser;

        return $this;
    }

    public function getDeleted(): ?bool
    {
        return $this->deleted;
    }

    public function setDeleted(bool $deleted): self
    {
        $this->deleted = $deleted;

        return $this;
    }
}

, когда я пытаюсь получить все комментарии от одного user, я использую эту функцию

$coms_by_user = $com_repo->findBy(['auteur' => $user->getId()]);

$ user - это параметр маршрута из / users / profile / $ user, и он работает и возвращает мне такой массив для пользователя с 2 опубликованными комментариями:

array:2 [▼
  0 => Comments {#842 ▼
    -id: 11
    -auteur: Users {#497 ▼
      -id: 21
      -username: "testtttt"
      -password: "$argon2i$v=19$m=65536,t=4,p=1$S01Da1dseVBDQTBBZ0xJcQ$vvKB4Kfa7GLkhyMhbUqyC7PBjLA1doGxWPBPaXkd5bw"
      -email: "test.symfony@symfony.com"
      -firstName: "test"
      -lastName: "lol"
      -roles: array:1 [▶]
      -collection: PersistentCollection {#567 ▶}
      -wishlists: PersistentCollection {#493 ▶}
      -registeredAt: DateTime @1580322507 {#495 ▶}
      -comments: PersistentCollection {#427 ▶}
      -commentsOnUser: PersistentCollection {#429 ▶}
      -image: null
    }
    -postedAt: DateTime @1578960000 {#840 ▶}
    -content: "Hello !"
    -flagged: 0
    -validated: false
    -postedOnCard: Cards {#873 ▼
      +__isInitialized__: false
      -cardId: 117
      -cardName: null
      -cardSetNum: null
      -cardAlter: null
      -cardImage: null
      -cardColor: null
      -cardRarity: null
      -cardSet: null
      -cardType: null
      -comments: null
       …2
    }
    -postedOnUser: null
    -deleted: false
  }
  1 => Comments {#871 ▶}
]

Как видите, doctrine произвел автоматическое объединение с пользователями, предоставив мне имя пользователя и все данные автора комментария. Однако, это не дало мне соединение между postsOnCard и картой, на которой был размещен комментарий. Так что я не могу назвать название карты и все остальное. (та же проблема, что и для между postsOnUser и пользователями)

ТАК Я пытался сделать свой собственный запрос, но я пытался все, и ничего, похоже, не работает. Я всегда получаю пустой массив. Метод, который я сделал, чтобы получить все комментарии по имени пользователя (из параметра route) с 3-мя объединениями (users, postsOnCard, postsOnUser)

/**
     * @return Comments[]
     * @param string $author
     */
    public function findAllWithLocation (string $author) {
        return $this->createQueryBuilder('com')
            ->addSelect('auteur', 'onCard', 'onUser')
            ->join('com.auteur'      , 'auteur')
            ->join('com.postedOnCard', 'onCard')
            ->join('com.postedOnUser', 'onUser')

            ->andWhere('auteur.username = :author')
            ->setParameter('author', $author)

            ->getQuery()
            ->getArrayResult();
    }

, метод выполняется, но ничего не возвращает. Я действительно не понимаю. Также, если кто-то может объяснить мне, почему все методы find () / findBy / findOneBy ect по умолчанию doctrine фактически автоматически объединяются с пользователями. Имеет ли таблица пользователей какие-то привилегии?

1 Ответ

2 голосов
/ 29 января 2020

Соединением по умолчанию является внутреннее соединение. Это означает, что запись должна существовать.

Полагаю, в вашей таблице комментариев есть только onUser или onCard, но редко или никогда оба. Вызов ->join('com.onUser', 'onUser') и ->join('com.onCard', 'onCard') приведет к тому, что записи не будут возвращены.

Это можно исправить, используя leftJoin вместо join (остальное остается прежним).

Doctrine обычно возвращает прокси-объекты, когда отношение не загружено. Однако, поскольку ваша таблица (сущность) содержит идентификатор пользователя, который должен быть загружен, и этот пользователь уже существует в кэше doctrine, пользователь будет помещен туда вместо прокси-объекта. Очевидно, что это не относится к другим отношениям, которые у вас есть в вашем комментарии.

Таблица пользователей не имеет особых привилегий.

Если вы всегда хотите загрузить некоторые отношения сущности, посмотрите на готовую загрузку (добавив fetch="EAGER" к аннотации @ManyToOne).

...