I made the entities, I know how to insert the flat elements from the array, but I don’t know how to insert the actors in the people table and make an entry inside relations table with the actor id, the type(actor/director/genres), and the subjectid(movie id).
I’ve read the symfony and doctrine documentation and I didn’t find a solution.
protected function sendTODB(array $movie){
//Entity Manager
$em = $this->getDoctrine()->getManager();
$movie = new Movies();
$movie->setTitle($movie['title']);
$movie->setDescription($movie['description']);
$people= new People();
$people->setRole();
}
I don’t understand what the RelTable model is for, and I also don’t understand what the relations database table is for. There seems to be nothing in the JSON that needs those. Also, I don’t see anywhere in the JSON a reference to a role for an actor. What’s that?
As for the general gist, using Doctrine, you would do something like this
Movie model:
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
class Movie
{
/**
* @var int
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @var string
* @ORM\Column(type="string", length=255)
*/
private $title;
/**
* @var string
* @ORM\Column(type="text")
*/
private $description;
/**
* @var array|Actor[]|Collection
* @ORM\OneToMany(target="App\Entity\Actor")
*/
private $actors;
public function __construct(string $title, string $description)
{
$this->title = $title;
$this->description = $description;
$this->actors = new ArrayCollection();
}
public function addActor(Actor $actor)
{
$this->actors->add($actor);
}
}
Actor model:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
class Actor
{
/**
* @var int
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @var string
* @ORM\Column(type="string", length=255)
*/
private $name;
public function __construct(string $name)
{
$this->nam = $name;
}
}
Controller:
<?php
$em = $this->getDoctrine()->getManager();
$data = json_decode($jsonString, true);
foreach ($data as $movieData) {
$movie = new Movie($movieData['title'], $movieData['description']);
foreach ($movieData['actors'] as $actorData) {
$actor = new Actor($actorData['name']);
$em->persist($actor);
$movie->addActor($actor);
}
$em->persist($movie);
$em->flush();
}
Note that I’ve changed two things quite drastically:
All model names are singular, as a single class represents one movie, not several movies, so the name movies is just plain confusing
The models have constructors with required fields. For example you cannot create a movie object without supplying a name, since a movie without a name doesn’t make any sense.
Sorry, I wasn’t too clear.
It was just an example, above I simplified and changed the names. The JSON is bigger and it has multiple arrays, I just wanted to show that it is a multidimensional array.
The relations table is for relations between “people” and movies. And is not limited just to people, is for genres too, or media.
If I have an actor that is in multiple movies I would have to have duplicate data in my DB. This way I store the people in the people table, the movie in movie table and make relation between them in the relations table.
For example
Movie1 - actor Meryl Streep
Movie 2 - actor Meryl Streep
The DB would be something like this
movies
- 1(id) | Movie1 (title) | Balblabla(description)
- 2(id) | Movie2 (title) | Balblabla(description)
people
- 1(id) | Meryl Streep | actor(role)
- 2(id) | Martin Scorsese | director(role)
this is the relation between the movie and the actor
relations
- 1(id) 1(movieid - Movie1) | actor(type) | 1(typeid - people id of meryl streep)
- 2(id) 1(movieid - Movie1) | director(type) | 2(typeid - people id of martin scorsese)
Right, but then I would say the role column on the people table is out of place, since one person can be actor in one movie, and be a director in another movie, or indeed actor, writer and director in the same movie (like Quintin Tarantino in Reservoir Dogs).
So I would suggest to ditch that column, and keep that on the relations table instead.
A rough outline of the code would be
foreach (movies as movieData)
movie = new Movie(movieData)
foreach (actors as actorData)
actor = actorRepository.findActor(actorData)
if !actor
actor = new Actor(actorData)
relation = new Relation(movie, actor, relationType)
save(actor)
save(relation)
save(movie)
I’ll leave it to you to translate that to Doctrine code. Shouldn’t be too hard. And just holler if you get stuck