У меня есть следующие две таблицы и соответствующие две сущности, показанные внизу этого поста.time_unit
состоит только из нескольких предустановленных записей: s/second/1
, m/minute/60
, h/hour/360
и т. Д.
Мне нужно создать новое расписание.Хотя это и не показано, у меня есть несколько типов расписаний, которые по-разному используют предоставленные данные, и поэтому хотят разместить установщики внутри сущности (либо конструктора, либо какого-либо метода интерфейса) вместо службы.Чтобы создать новое расписание, я выполняю $scheduleService->create(['name'=>'the schedule name', 'other_data'=>123, 'time_unit'=>'h']);
.
<?php
namespace Michael\App\Service;
use Michael\App\Entity;
class ScheduleService
{
public function create(array $params):int {
//validation as applicable
$schedule=new Entity\Schedule($params);
$this->em->persist($schedule);
$this->em->flush();
return $schedule->getId();
}
}
и затем добавляю в конструктор Schedule следующий конструктор:
public function __construct(array $params) {
$this->setName($params['name']);
$this->setOtherData($params['other_data']);
$timeUnit=new TimeUnit();
$timeUnit->setUnit($params['time_unit']);
$this->setTimeUnit($timeUnit);
}
Но это не будет работать, потому что я создаюновый экземпляр TimeUnit и Doctrine будут жаловаться.
В качестве альтернативы я могу передать Schedule диспетчер сущностей, но все, что я прочитал, утверждает, что это плохая практика.
Как следуетодин создать новую сущность, которая содержит другую существующую сущность?
Схема и основные сущности без дополнительной логики показаны ниже:
CREATE TABLE schedule (id INT NOT NULL, time_unit VARCHAR(1) NOT NULL, name VARCHAR(45) NOT NULL, other_data VARCHAR(45) NOT NULL, INDEX fk_schedule_time_unit_idx (time_unit), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB;
CREATE TABLE time_unit (unit VARCHAR(1) NOT NULL, name VARCHAR(45) NOT NULL, seconds INT NOT NULL, PRIMARY KEY(unit)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB;
ALTER TABLE schedule ADD CONSTRAINT FK_5A3811FB7106057E FOREIGN KEY (time_unit) REFERENCES time_unit (unit);
schedule.php
<?php
namespace Michael\App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Schedule
*
* @ORM\Table(name="schedule", indexes={@ORM\Index(name="fk_schedule_time_unit_idx", columns={"time_unit"})})
* @ORM\Entity
*/
class Schedule
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="NONE")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=45)
*/
private $name;
/**
* @var string
*
* @ORM\Column(name="other_data", type="string", length=45)
*/
private $other_data;
//Not included since docs state one shouldn't map foreign keys to fields in an entity
//private $time_unit;
/**
* @var \TimeUnit
*
* @ORM\ManyToOne(targetEntity="TimeUnit")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="time_unit", referencedColumnName="unit")
* })
*/
private $timeUnit;
/**
* Set id.
*
* @param int $id
*
* @return Schedule
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get id.
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name.
*
* @param string $name
*
* @return Schedule
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name.
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set otherData.
*
* @param string $otherData
*
* @return Schedule
*/
public function setOtherData($otherData)
{
$this->other_data = $otherData;
return $this;
}
/**
* Get otherData.
*
* @return string
*/
public function getOtherData()
{
return $this->other_data;
}
/**
* Set timeUnit.
*
* @param TimeUnit $timeUnit (not a string)
*
* @return Schedule
*/
public function setTimeUnit($timeUnit)
{
$this->timeUnit = $timeUnit;
return $this;
}
/**
* Get timeUnit.
*
* @return TimeUnit (not a string)
*/
public function getTimeUnit()
{
return $this->timeUnit;
}
}
time_unit.php
<?php
namespace Michael\App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* TimeUnit
*
* @ORM\Table(name="time_unit")
* @ORM\Entity
*/
class TimeUnit
{
/**
* @var string
*
* @ORM\Column(name="unit", type="string", length=1)
* @ORM\Id
* @ORM\GeneratedValue(strategy="NONE")
*/
private $unit;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=45)
*/
private $name;
/**
* @var int
*
* @ORM\Column(name="seconds", type="integer")
*/
private $seconds;
/**
* Set unit.
*
* @param string $unit
*
* @return TimeUnit
*/
public function setUnit($unit)
{
$this->unit = $unit;
return $this;
}
/**
* Get unit.
*
* @return string
*/
public function getUnit()
{
return $this->unit;
}
/**
* Set name.
*
* @param string $name
*
* @return TimeUnit
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name.
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set seconds.
*
* @param int $seconds
*
* @return TimeUnit
*/
public function setSeconds($seconds)
{
$this->seconds = $seconds;
return $this;
}
/**
* Get seconds.
*
* @return int
*/
public function getSeconds()
{
return $this->seconds;
}
}