我正在开发twig fiddle,相当于Twig语言的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';
// ...
}
可以想象,我可以从UI中添加/删除模板。
Fiddle 的 id 是 Fiddle 实体的一部分,所以如果我想第一次保留模板,我首先需要保留小提琴。我使用教义事件支持器来做到这一点(如果有兴趣,请参阅修订历史)。但是,如果我尝试将模板添加到已经存在的小提琴并保存,我会得出以下异常:
类型为 Fuz''AppBundle''Entity''FiddleTemplate 的实体缺少 为字段"小提琴"分配 ID。标识符生成策略 此实体要求在 ID 字段之前填充 调用 EntityManager#persist()。如果要自动生成 标识符 相反,您需要调整元数据映射 因此。
听起来很合乎逻辑,因为我需要在持久之前将小提琴的实例传播到模板中。
但是我没有发现任何在 Fiddle 实体上触发的 Doctrine 事件,即使 templates
成为实体的一部分,也不会调用preUpdate
,因为它不需要任何更新。在 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 实体传播到所有模板?
制作Fiddle::addTemplate($template)
方法不是更好吗,该方法会将模板添加到集合($this->templates->add($template)
)并将链接设置为自身($template->setFiddle($this)
)。AFAIK,如果小提琴是模型的聚合根,则推荐使用此方法。