Я занимаюсь разработкой веточки скрипки, js / sql / php-fiddle, эквивалентной для Язык веток. Мы можем добавить несколько шаблонов для отображения результата, и у меня есть следующие объекты:
class Fiddle
{
/**
* @var ArrayCollection[FiddleTemplate]
*
* @ORM\OneToMany(targetEntity="FiddleTemplate", mappedBy="fiddle", cascade={"all"}, orphanRemoval=true)
*/
protected $templates;
// ...
}
class FiddleTemplate
{
/**
* @var Fiddle
*
* @ORM\ManyToOne(targetEntity="Fiddle", inversedBy="templates")
* @ORM\JoinColumn(name="fiddle_id", referencedColumnName="id", onDelete="cascade")
* @ORM\Id
*/
protected $fiddle;
/**
* @var string
*
* @ORM\Column(name="filename", type="string", length=64)
* @ORM\Id
*/
protected $filename = 'main.twig';
// ...
}
Как вы можете себе представить, я могу добавлять / удалять шаблоны из пользовательского интерфейса.
Идентификатор Fiddle принимает участие в сущности Fiddle, поэтому, если я хочу сохранить шаблоны в первый раз, сначала нужно сохранить скрипку. Я делаю это, используя обработчик событий Doctrine (см. Историю изменений, если интересно). Но если я пытаюсь добавить шаблон в уже существующую скрипту и сохранить, я получаю следующее исключение:
Объект типа Fuz \ AppBundle \ Entity \ FiddleTemplate отсутствует
присвоенный идентификатор для поля «скрипка». Стратегия генерации идентификатора для
эта сущность требует, чтобы поле ID было заполнено до
EntityManager # persist () вызывается. Если вы хотите автоматически генерируется
вместо идентификаторов вам нужно настроить отображение метаданных
соответственно.
Звучит достаточно логично, так как мне нужно распространить экземпляр Fiddle на шаблон перед сохранением.
Но я не нашел ни одного события Доктрины, запущенного на сущности Скрипача, preUpdate
не называется, даже если templates
принимает участие в сущности, потому что не требует обновления. Только pre/postPersist
событие запускается для объекта FiddleTemplate, но это не сильно помогает.
В настоящее время я делаю что-то довольно уродливое ИМХО: прежде чем продолжать, я называю spreadFiddle
на моей сущности:
$fiddle->spreadFiddle();
$this->em->persist($fiddle);
$this->em->flush();
Метод выглядит так:
public function spreadFiddle()
{
foreach ($this->templates as $template)
{
$template->setFiddle($this);
}
}
Вот мой вопрос:
Есть ли лучший способ (используя события или аннотации) распространять сущность Fiddle на все шаблоны?
Не лучше ли сделать Fiddle::addTemplate($template)
метод, который добавит шаблон в коллекцию ($this->templates->add($template)
) и установите ссылку на себя ($template->setFiddle($this)
). AFAIK, это рекомендуемый способ, если Fiddle является корнем агрегации вашей модели.
Других решений пока нет …