skip to Main Content

I have a page that displays information about a movie. I recover in GET the id of the film. What I would like to do is retrieve the comments for each film (there is a filmId column in my table linked to the primary id of the film table)

   /**
     * @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
        ]);
    }

when I make a $comments = $comRepo->findBy(array(‘id’ => $id)); I get some comments, but based on their id and NOT the film id (the comment with id 1 will be displayed on the film with id 1, but for example a comment with id 4 and the filmId a 1 will not appear on film 1, but on the film with id 4)

I tried to access the filmId field by simply making a $comments = $comRepo->findBy(array (‘filmId’ => $ id)); but i get the error :

An exception occurred while executing ‘SELECT t0.id AS id_1, t0.content AS content_2, t0.created_at AS created_at_3, t0.author_id AS author_id_4 FROM comment t0 WHERE comment_film.film_id = ?’ with params [“1”]:
SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘comment_film.film_id’ in ‘where clause’

I tried a personalized request with, in my Comment repository:


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

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

        return $query->getResult();
    }

But it doesn’t seem to work..

Where do I go to make a request like this ?
How to modify the request, which seems erroneous, from symfony without disorganizing everything? or is there a better method to correct the problem?

This is my Comment Entity

<?php

namespace AppEntity;

use AppEntityFilm;
use DoctrineORMMapping as ORM;

/**
 * @ORMEntity(repositoryClass="AppRepositoryCommentRepository")
 */
class Comment
{
    /**
     * @ORMId()
     * @ORMGeneratedValue()
     * @ORMColumn(type="integer")
     */
    private $id;

    /**
     * @ORMManyToOne(targetEntity="AppEntityUser", inversedBy="comments")
     * @ORMJoinColumn(nullable=false)
     */
    private $author;

    /**
     * @ORMManyToMany(targetEntity="AppEntityFilm", inversedBy="comments")
     * @ORMJoinColumn(nullable=false)
     */
    private $filmId;

    /**
     * @ORMColumn(type="text")
     */
    private $content;

    /**
     * @ORMColumn(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;
    }
}

I think it is possible that the error comes from annotations, because starting on symfony during the make: entity, I defined types relations which I corrected later in phpmyadmin, but not the code. For example we can see that filmId is in ManyToMany, but I think it should be in OneToOne (FilmId can only have one id and an id can only correspond to one filmId), but I’m afraid that if I change certain things it breaks everything.

2

Answers


  1. If you have set up your ORM relations correctly, it should be as simple as:

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

    You might be missing a mapping in Film.php.

    Here’s an XML example, should be easy enough to convert to annotations:

    In film:

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

    In comments:

    <many-to-one field="film" target-entity="App...Film" inversed-by="comments"/>
    
    Login or Signup to reply.
  2. First of all, I advise you to read more about the relations between entities.

    Because, the current annotations says that you can have a lot of comments on many films. It’s not right. One comment may belong to one film. One movie can have many comments.

    Also, I want to note that, as far as I know, @JoinColumn should be in a child entity, that is, where the link to FK is contained.
    Therefore, your entities should look like this:

    Comment:

    <?php
    
    namespace AppEntity;
    
    use AppEntityFilm;
    use DateTimeInterface;
    use DoctrineORMMapping as ORM;
    
    /**
     * @ORMEntity(repositoryClass="AppRepositoryCommentRepository")
     */
    class Comment
    {
        /**
         * @ORMId()
         * @ORMGeneratedValue()
         * @ORMColumn(type="integer")
         */
        private $id;
    
        /**
         * @ORMManyToOne(targetEntity="AppEntityUser", inversedBy="comments")
         */
        private $author;
    
        /**
         * @ORMManyToOne(targetEntity="AppEntityFilm", 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 
         * @ORMJoinColumn(name="film_id", referencedColumnName="id", nullable=false)
         */
        private $film;
    
        /**
         * @ORMColumn(type="text")
         */
        private $content;
    
        /**
         * @ORMColumn(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;
        }
    }
    

    Film:

    <?php
    
    namespace AppEntity;
    
    use DoctrineCommonCollectionsArrayCollection;
    use DoctrineCommonCollectionsCollection;
    use DoctrineORMMapping as ORM;
    
    /**
     * @ORMEntity(repositoryClass="AppRepositoryFilmRepository")
     */
    class Film
    {
        /**
         * @ORMId()
         * @ORMGeneratedValue()
         * @ORMColumn(type="integer")
         */
        private $id;
        /**
         * @ORMOneToMany(targetEntity="AppEntityComment", 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;
        }
    }
    

    So, now, you can retrieve your comments via:

    /**
         * @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
            ]);
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search