Я разрабатываю скрипку для завивки, эквивалентную js/sql/php-скрипке для языка Twig. Мы можем добавить несколько шаблонов для отображения результата, и у меня есть следующие объекты:
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 event suscriber (см. Историю изменений, если это интересно). Но если я попытаюсь добавить шаблон к уже существующей скрипке и сохранить, я придумаю следующее исключение:
Объекту типа Fuz\AppBundle\Entity\FiddleTemplate отсутствует назначенный идентификатор для поля 'скрипка'. Стратегия генерации идентификатора для этого объекта требует, чтобы поле ID было заполнено до вызова EntityManager # persist(). Если вы хотите автоматически сгенерировать идентификаторы, вам нужно соответствующим образом скорректировать сопоставление метаданных.
Звучит логика достаточно, так как мне нужно распространить экземпляр Fiddle до шаблона, прежде чем он будет продолжаться.
Но я не обнаружил какого-либо события Doctrine, запущенного в сущности 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)
) и установить ссылку на self ($template->setFiddle($this)
). AFAIK, рекомендуется, если Fiddle является корнем агрегации вашей модели.
Fiddle::addTemplate($template)
, который добавит шаблон в коллекцию ($this->templates->add($template)
) и установит ссылку на себя ($template->setFiddle($this)
). AFAIK, это рекомендуемый способ, если Fiddle является корнем агрегации вашей модели.$fiddle->setTemplates()
похоже, не$fiddle->setTemplates()
после проверки формы.