Автоматически распространять личность при сохранении поля @OneToMany

0

Я разрабатываю скрипку для завивки, эквивалентную 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 на все шаблоны?

  • 0
    Разве не лучше создать Fiddle::addTemplate($template) , который добавит шаблон в коллекцию ( $this->templates->add($template) ) и установит ссылку на себя ( $template->setFiddle($this) ). AFAIK, это рекомендуемый способ, если Fiddle является корнем агрегации вашей модели.
  • 0
    Хм, на самом деле это не так просто, потому что моя коллекция форм автоматически заполняется Symfony2, а мой $fiddle->setTemplates() похоже, не $fiddle->setTemplates() после проверки формы.
Показать ещё 2 комментария
Теги:
one-to-many
doctrine2

1 ответ

1
Лучший ответ

Разве не лучше сделать Fiddle::addTemplate($template), который добавит шаблон в коллекцию ($this->templates->add($template)) и установить ссылку на self ($template->setFiddle($this)). AFAIK, рекомендуется, если Fiddle является корнем агрегации вашей модели.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню