Symfony2表单集合自动持久化
我正在尝试嵌入一个表单集合。我有一个任务表单,其中包含一组标记表单:Symfony2表单集合自动持久化,symfony,doctrine-orm,symfony-forms,Symfony,Doctrine Orm,Symfony Forms,我正在尝试嵌入一个表单集合。我有一个任务表单,其中包含一组标记表单: public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('tags', 'collection', array('type' => new TagType())); } 任务实体包含与标记的一对多关系(无级联持久): 标记实体包含与任务的多对一关系: /** * @ORM\ManyT
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('tags', 'collection', array('type' => new TagType()));
}
任务实体包含与标记的一对多关系(无级联持久):
标记实体包含与任务的多对一关系:
/**
* @ORM\ManyToOne(targetEntity="Task", inversedBy="tags")
* @ORM\JoinColumn(name="task_id", referencedColumnName="id")
*/
protected $task;
我现在有一个控制器,它可以编辑其任务的所有标记。如果表单已提交且有效,我希望遍历所有标记并决定是否保存标记,但在我的情况下,如果调用了$em->flush()
,则会自动更新和保留每个标记,甚至不会对任务或任何标记调用$em->persist()
public function editTaskAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$task = $em->getRepository('AcmeTaskBundle:Task')->find($id);
$form = $this->createForm(new TaskType(), $task);
$form->handleRequest($request);
if ($form->isValid())
{
foreach ($task->getTags() as $tag)
{
// TODO decide whether to save the tag or not
}
$em->flush();
}
return array('form' => $form->createView());
}
我真的不明白我错过了什么。数据具体保存在哪里?当您使用EntityManager检索
$task
时($task=$em->getRepository('AcmeTaskBundle:task')->find($id);
),该实体由EntityManager自动管理,因此$em->persist($task)代码>是隐式的
例如,在您的createTaskAction()
中,您不是通过创建任务来获得任务的($Task=newtask();
)
在您的情况下,最好是通过执行类似于$task->removeTag($tag)的操作来删除foreach($task->getTags()as$tag)
中不需要的标记代码>用于任何不需要的标记。这不是执行此操作的正确位置。您应该使用prePersist
,在其中您可以访问发送到数据库的所有数据。在这里,您可以决定是否插入新行。
以下是生命周期的工作原理。多亏了我在标记实体类中使用了生命周期回调:
use Doctrine\ORM\Event\PreUpdateEventArgs;
/**
* @ORM\HasLifecycleCallbacks
*/
class Tag
{
/**
* @ORM\PreUpdate()
*/
public function preUpdate(PreUpdateEventArgs $event)
{
if ($event->getEntity() instanceof Tag)
{
if ($event->hasChangedField('name') && $conditionToAvoidUpdatingEntity)
{
$event->setNewValue('name', $event->getOldValue('name'));
}
}
}
}
use Doctrine\ORM\Event\PreUpdateEventArgs;
/**
* @ORM\HasLifecycleCallbacks
*/
class Tag
{
/**
* @ORM\PreUpdate()
*/
public function preUpdate(PreUpdateEventArgs $event)
{
if ($event->getEntity() instanceof Tag)
{
if ($event->hasChangedField('name') && $conditionToAvoidUpdatingEntity)
{
$event->setNewValue('name', $event->getOldValue('name'));
}
}
}
}