Запрос связанного поля в symfony - PullRequest
1 голос
/ 25 марта 2020

У меня есть страница, которая отображает информацию о MOV ie. Я возвращаюсь в GET id фильма. Я хотел бы получить комментарии для каждого фильма (в моей таблице есть столбец filmId, связанный с основным идентификатором таблицы фильмов)

   /**
     * @Route("/user/film/{id}", name="film")
     */
    public function film(FilmRepository $repo, CommentRepository $comRepo, EntityManagerInterface $em, Request $req, $id)
    {
        $film = $repo->find($id);

        $comments = $comRepo->findBy(array('id' => $id));





        return $this->render('film/film.html.twig', [
            'controller_name' => 'FilmController',
            'film' => $film,
            'comments' => $comments
        ]);
    }

, когда я делаю комментарии $ = $ comRepo-> findBy (array ('id' => $ id)); Я получаю некоторые комментарии, но на основе их идентификатора и NOT идентификатора фильма (комментарий с идентификатором 1 будет будет отображаться в фильме с идентификатором 1, но, например, комментарий с идентификатором 4 и filmId a 1 не будет отображаться в фильме 1, но в фильме с идентификатором 4)

Я попытался получить доступ к полю filmId просто сделав $ comments = $ comRepo-> findBy (array ('filmId' => $ id)); , но я получаю ошибку:

An возникла исключительная ситуация при выполнении 'SELECT t0.id AS id_1, t0.content AS content_2, t0.created_at AS созданный_at_3, t0.author_id AS author_id_4 ОТ комментария t0 ГДЕ comment_film.film_id =?' с параметрами ["1"]: SQLSTATE [42S22]: столбец не найден: 1054 Неизвестный столбец 'comment_film.film_id' в 'предложении where'

Я попытался выполнить персонализированный запрос с, в мой репозиторий комментариев:


public function findAllWithFilmId($filmId) 
    {
        $em = $this->getEntityManager();

        $query = $em->createQuery(
            'SELECT c
            FROM App\Entity\Comment c
            WHERE c.filmId = :filmId'
        )->setParameter('filmId', $filmId);

        return $query->getResult();
    }

Но, похоже, он не работает ..

Где мне go сделать такой запрос? Как сделать изменить запрос, который кажется ошибочным, из symfony без дезорганизации всего? или есть лучший способ исправить проблему?

Это мой комментарий сущности

<?php

namespace App\Entity;

use App\Entity\Film;
use Doctrine\ORM\Mapping as ORM;

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

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

    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\Film", inversedBy="comments")
     * @ORM\JoinColumn(nullable=false)
     */
    private $filmId;

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

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



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

    public function getAuthor(): ?User
    {
        return $this->author;
    }

    public function setAuthor(?User $author): self
    {
        $this->author = $author;

        return $this;
    }


    public function getFilmId(): ?Film
    {
        return $this->filmId;
    }

    public function setFilmId(?Film $filmId): self 
    {
        $this->filmId = $filmId;

        return $this;
    }

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

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

        return $this;
    }

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

    public function setCreatedAt(\DateTimeInterface $createdAt): self
    {
        $this->createdAt = $createdAt;

        return $this;
    }
}

Я думаю, возможно, что ошибка происходит от аннотаций , потому что начиная с symfony во время make: entity, я определял отношения типов, которые позже исправил в phpmyadmin, но не код. Например, мы можем видеть, что filmId находится во ManyToMany, но я думаю, что он должен быть в OneToOne (FilmId может иметь только один идентификатор, а идентификатор может соответствовать только одному filmId), но я боюсь, что если я изменю определенные вещи, то это ломает все .

Ответы [ 2 ]

2 голосов
/ 25 марта 2020

Если вы правильно настроили отношения ORM, это должно быть просто:

$film = $repo->find($id);
$comments = $film->getComments();

Возможно, вам не хватает отображения в фильме. php.

Вот XML пример, должен быть достаточно простым для преобразования в аннотации:

В фильме:

<one-to-many field="comments" target-entity="App\...\Comments" mapped-by="film"/>

В комментариях:

<many-to-one field="film" target-entity="App\...\Film" inversed-by="comments"/>
0 голосов
/ 27 марта 2020

Прежде всего, советую прочитать подробнее об отношениях между сущностями .

Потому что текущие аннотации говорят, что вы можете иметь много комментариев ко многим фильмам. Это не правильно. Один комментарий может принадлежать одному фильму. Один мов ie может иметь много комментариев.

Также хочу отметить, что, насколько мне известно, @JoinColumn должен быть в дочерней сущности, то есть там, где содержится ссылка на FK. Следовательно, ваши сущности должны выглядеть следующим образом:

Комментарий:

<?php

namespace App\Entity;

use App\Entity\Film;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;

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

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="comments")
     */
    private $author;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Film", inversedBy="comments")
     * Here we set property for our table and property of foreign table to map our comment to the right film
     * nullable, because comment couldn't be without film 
     * @ORM\JoinColumn(name="film_id", referencedColumnName="id", nullable=false)
     */
    private $film;

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

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


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

    public function getAuthor(): ?User
    {
        return $this->author;
    }

    public function setAuthor(?User $author): self
    {
        $this->author = $author;

        return $this;
    }


    public function getFilmId(): ?Film
    {
        return $this->filmId;
    }

    public function setFilmId(?Film $filmId): self
    {
        $this->filmId = $filmId;

        return $this;
    }

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

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

        return $this;
    }

    public function getCreatedAt(): ?DateTimeInterface
    {
        return $this->createdAt;
    }

    public function setCreatedAt(DateTimeInterface $createdAt): self
    {
        $this->createdAt = $createdAt;

        return $this;
    }
}

Фильм:

<?php

namespace App\Entity;

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

/**
 * @ORM\Entity(repositoryClass="App\Repository\FilmRepository")
 */
class Film
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;
    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Comment", mappedBy="film")
     */
    private $comments;

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

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

    public function setId($id)
    {
        $this->id = $id;
        return $this;
    }

    public function getComments(): Collection
    {
        return $this->comments;
    }

    public function setComments(Collection $comments): Film
    {
        $this->comments = $comments;
        return $this;
    }
}

Итак, теперь вы можете получить свои комментарии с помощью:

/**
     * @Route("/user/film/{id}", name="film")
     */
    public function film($id)
    {
        /** @var null|EntityManager $entityManager */
        $entityManager = $this->get('doctrine.orm.entity_manager');
        if (null == ($film = $entityManager->getRepository(Film::class)->find($id))){
            throw new NotFoundHttpException('Film not found');
        }

        $comments = $film->getComments();

        return $this->render('film/film.html.twig', [
            'film' => $film,
            'comments' => $comments
        ]);
    }
...