短篇故事(编辑)
可以存储数组而不是映射关联。在Symfony2中,使用collection Field Type很容易做到这一点。例如,使用此技术,您可以存储填充数组事件字段的文本字段数组。然而,要更新数组,有一个技巧,@Vadim Ashikhman在公认的答案中很好地解释了这个技巧。
长篇大论
有时,存储数组比存储映射关联更有用,效率更高。但是,一旦创建,如果该数组的大小不变,更新该数组仍然很复杂。
很多人都有similar issue,但是没有人找到解决这个问题的合适方法。

一个团队可以组织许多活动。这些事件只是使用Doctrine存储在数组中,而不是使用OneToMany关联。因此,实体事件不会与Doctrine映射。
实体事件(未与Doctrine映射)
<?php
namespace Acme\TestBundle\Entity;
...
class Event
{
/**
* @Assert\NotBlank
*/
private $name;
public function setName($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}实体团队
<?php
namespace Acme\TestBundle\Entity;
...
/**
* @ORM\Entity()
* @ORM\HasLifecycleCallbacks
* @ORM\Table(name="teams")
*/
class Team
{
/**
* @ORM\Column(type="array")
* @var array
*/
protected $events;
public function addEvent($event)
{
if (!in_array($event, $this->events, true)) {
$this->events[] = $event;
}
return $this;
}
public function removeEvent($event)
{
if (false !== $key = array_search($event, $this->events, true)) {
unset($this->events[$key]);
$this->events = array_values($this->events);
}
return $this;
}
public function getEvents()
{
return $this->events;
}
public function setEvents(array $events)
{
$this->events = array();
foreach ($events as $event) {
$this->addEvent($event);
}
return $this;
}事件表单
<?php
namespace Acme\TestBundle\Form\Type;
...
class EventType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->add('name', 'text');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\TestBundle\Entity\Event',
'cascade_validation' => true,
));
}
...
}团队形式
<?php
namespace Acme\TestBundle\Form\Type;
...
class TeamType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->add('events','collection', array(
'type' => new EventType(),
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'by_reference' => false,
'options' => array('data_class' => 'Acme\TestBundle\Entity\Event'),
)
);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\TestBundle\Entity\Team',
));
}
...
}控制器
/**
* Update a team
*
* @Route("update/{team_id}", name="updateTeamFromId")
* @Template("AcmeTestBundle:Team:teamUpdate.html.twig")
*/
public function updateTeamAction($team_id, Request $request)
{
$em = $this->getDoctrine()->getManager();
$repository= $em->getRepository('AcmeTestBundle:Team');
$team_to_update = $repository->find($team_id);
$form = $this->createForm(new teamType(), $team_to_update);
if ($request->getMethod() == 'POST')
{
$form->bind($request);
if ($form->isValid()){
$em->persist($team_to_update);
$em->flush();
return $this->redirect($this->generateUrl('homepage')) ;
}
}
return array(
'form' => $form->createView(),
'team_id' => $team_id,
);
}发布于 2012-11-05 20:28:52
您可以在控制器中尝试以下操作:
public function updateTeamAction($team_id, Request $request)
{
$em = $this->getDoctrine()->getManager();
$repository= $em->getRepository('AcmeTestBundle:Team');
$team_to_update = $repository->find($team_id);
$form = $this->createForm(new teamType(), $team_to_update);
if ($request->getMethod() == 'POST')
{
$form->bind($request);
if ($form->isValid()){
$events = $team_to_update->getEvents();
foreach($events as $key => $value){
$team_to_update->removeEvent($key);
}
$em->flush();
$team_to_update->setEvents($events);
$em->persist($team_to_update);
$em->flush();
return $this->redirect($this->generateUrl('homepage')) ;
}
}
return array(
'form' => $form->createView(),
'team_id' => $team_id,
);
}可能有一个更好的方法来做这件事,我知道这不是一个很好的方法,但在你(或其他人)找到解决方案之前,你可以把它作为一个临时解决方案。
https://stackoverflow.com/questions/13227658
复制相似问题