我正在开发twig小提琴,js / sql / php-fiddle相当于Twig language。我们可以添加几个模板来渲染结果,我有以下实体:
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';
// ...
}
您可以想象,我可以在UI中添加/删除模板。
Fiddle的id是Fiddle实体的一部分,所以如果我想第一次坚持模板,我首先需要坚持小提琴。我是使用Doctrine事件的主持人(如果感兴趣的话,请参阅rev历史)。但是,如果我尝试将模板添加到已存在的小提琴并保存,我会提出以下异常:
Fuz \ AppBundle \ Entity \ FiddleTemplate类型的实体缺少一个 为“小提琴”分配了ID。标识符生成策略 此实体需要先填充ID字段 调用EntityManager#persist()。如果要自动生成 您需要调整元数据映射 相应
听起来足够逻辑,因为我需要在持久化之前将Fiddle的实例传播到模板。
但是我没有在Fiddle实体上发现任何Doctrine事件,即使preUpdate
占用了实体,也没有调用templates
,因为它不需要任何更新。在FiddleTemplate实体上只触发了pre/postPersist
事件,但它没有那么大的帮助。
我目前做了一件非常丑陋的事情恕我直言:在坚持之前,我在我的实体上打电话给spreadFiddle
:
$fiddle->spreadFiddle();
$this->em->persist($fiddle);
$this->em->flush();
该方法如下:
public function spreadFiddle()
{
foreach ($this->templates as $template)
{
$template->setFiddle($this);
}
}
我的问题来了:
是否有更好的方法(使用事件或注释)将Fiddle实体传播到所有模板?
答案 0 :(得分:1)
制作Fiddle::addTemplate($template)
方法不是更好,它会将模板添加到集合($this->templates->add($template)
)并设置指向self($template->setFiddle($this)
)的链接。 AFAIK,如果Fiddle是您模型的聚合根,建议采用这种方式。