Связь между учением о сущности.Как ссылаться на «внешний ключ»? - PullRequest
0 голосов
/ 26 ноября 2018

В настоящее время я работаю с Symfony и Doctrine , и у меня возникли небольшие проблемы с ссылкой на два объекта.

У меня есть объект с именемcinema и еще один называется theater.Это отношение OneToMany, где в одном кинотеатре может быть много театров.

Я создаю cinema_id в theater, чтобы я мог связать кино и театр.

Я создал контроллер дляиспользовать данные из API и сохранять их в базе данных Postgres.Вот контроллер:

TheaterController

namespace App\Controller;

use GuzzleHttp\Client;
use App\Entity\Cinema;
use App\Entity\Theater;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class TheaterController extends AbstractController
{
/**
 * @Route("/theater", name="theater")
*/
public function Theater(Request $request)
{   
    $client = new Client();

    $res = $client->request('GET','api-content');

    $arrayContent = json_decode($res->getBody());

    foreach ($arrayContent as $value)
    {
        $entityManager = $this->getDoctrine()->getManager();

        $theater_cinema_id = $entityManager->getReference(Cinema::Cinema, $id);
        $theater->addId($theater_cinema_id);
        $theater_booking_cinema = 'value';
        $theater_booking_id = $value->id;

        $theater = new theater();
        $theater->setId($theater_cinema_id);
        $theater->setBookingCinema($theater_booking_cinema);
        $theater->setBookingId($theater_booking_id);
        //echo $theater;

        $entityManager->persist($theater);
        $entityManager->flush();
    }
  }
}

Моя проблема здесь в том, как я могу ссылаться на id с cinema на cinema_id с theater?Что я делаю не так?

Две сущности:

Cinema

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity(repositoryClass="App\Repository\CinemaRepository")
*/

class Cinema
{

/**
 * @ORM\Id()
 * @ORM\GeneratedValue()
 * @ORM\Column(type="integer")
 */
private $id;

/**
 * @ORM\Column(type="string", length=255)
 */
private $name;

/**
 * @ORM\Column(type="integer")
 */
private $is_active;

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

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

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

public function getName(): ?string
{
    return $this->name;
}

public function setName(string $name): self
{
    $this->name = $name;

    return $this;
}

public function getIsActive(): ?int
{
    return $this->is_active;
}

public function setIsActive(int $is_active): self
{
    $this->is_active = $is_active;

    return $this;
}

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

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

    return $this;
}

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

public function setUpdatedAt(\DateTimeInterface $updated_at): self
{
    $this->updated_at = $updated_at;

    return $this;
}
}

Theater

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity(repositoryClass="App\Repository\TheaterRepository")
*/

class Theater
{

/**
 * @ORM\Id()
 * @ORM\GeneratedValue()
 * @ORM\Column(type="integer")
 */
private $id;

/**
 * @ORM\ManyToOne(targetEntity="App\Entity\Cinema")
 * @ORM\JoinColumn(nullable=false)
 */
private $cinema;

/**
 * @ORM\Column(type="string", length=255)
 */
private $booking_cinema;

/**
 * @ORM\Column(type="integer")
 */
private $booking_id;

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

public function getCinema(): ?cinema
{
    return $this->cinema;
}

public function setCinema(?cinema $cinema): self
{
    $this->cinema = $cinema;

    return $this;
}

public function getBookingCinema(): ?string
{
    return $this->booking_cinema;
}

public function setBookingCinema(string $booking_cinema): self
{
    $this->booking_cinema = $booking_cinema;

    return $this;
}

public function getBookingId(): ?int
{
    return $this->booking_id;
}

public function setBookingId(int $booking_id): self
{
    $this->booking_id = $booking_id;

    return $this;
}
}

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

Как я понял, у вас много кинотеатров в одном театре.Итак, вы добавили следующий код к вашей Theater сущности:

// ...

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

// ...

/**
 * @var ArrayCollection $cinemas
 * @ORM\OneToMany(targetEntity="App\Entity\Theater", mappedBy="theater")
 */
public $cinemas;

// ...

/**
 * Theater constructor.
 */
public function __construct()
{
    $this->cinemas = new ArrayCollection();
}

// ...

/**
 * @return array
 */
public function getCinemas(): array
{
    return $this->cinemas->toArray()
}

/**
 * @return Theater
 */
public function addCinema(Cinema $cinema): self
{
    $this->cinemas->add($cinema);

    return $this;
}

// ...

и следующий код к вашей Cinema сущности:

// ...

use Doctrine\ORM\Mapping as ORM;

// ...

/**
 * @ORM\ManyToOne(targetEntity="App\Entity\Theater", inversedBy="cinemas")
 * @ORM\JoinColumn(name="theater_id", referencedColumnName="id", nullable=FALSE)
 */
 private $theater;

// ...

Затем вы можете получить доступ к вашейcinemas сущностей из Theater сущности:

$theaterRepository = $this->getDoctrine()->getManager()->getRepository(Theater::class);
$theater = $theaterRepository->findBy(['id' => 1]);
$cinemas = $theater->getCinemas(); // array

/** @var Cinema $cinema */
foreach($cinemas as $cinema) {
    // ...
}

Или добавьте новые Cinema к вашей Theater:

$theaterRepository = $this->getDoctrine()->getManager()->getRepository(Theater::class);
$theater = $theaterRepository->findBy(['id' => 1]);

$cinema = new Cinema();
// ...
$theater->addCinema($cinema)
// Persist, flush, e.t.c

О ArrayCollection, которые вы можете прочитать here

И вы можете получить доступ к вашему Theater объекту из любого Cinema объекта:

$cinemaRepository = $this->getDoctrine()->getManager()->getRepository(Cinema::class);
$cinema = $cinemaRepository->findBy(['id' => 1]);
$theater = $cinema->getTheater(); // Theater object

Или добавить Theater к вашему Cinema:

$cinema = new Cinema();
$theater = new Theater();
// ...
$cinema->setTheater($theater);
// ...
// Persist, flush, e.t.c
0 голосов
/ 26 ноября 2018

Doctrine - это ORM, что означает, что вам нужно думать не о таблицах, а о сущностях.Вы думаете не о внешних ключах, а об отношениях между сущностями.

Ваш API дает вам идентификатор кинотеатра, или вы можете получить к нему доступ другим способом?Вы можете найти кинотеатр, используя это:

$cinema = $entityManager->getRepository('App:Cinema')->findOneById($cinema_id);

Вы хотите сказать, к какому кинотеатру принадлежит театр?Используйте это:

$theater->setCinema($cinema); 

Doctrine сама построит и выполнит запросы для получения желаемых данных.

...