对不起,我的英语不好,我不是母语人士。如果需要,请随时更正我的文字。
这个问题真的很简单(它在本文的末尾),但我已经写了一些研究和测试的理由。
基本原理
如果你愿意,你可以跳过这个理由,直接跳到问题本身。
我已经尝试了几个小时,试图在 Symfony2 控制台上使用doctrine:generate:entities
和从反面保持多对多关系。doctrine:generate:crud
从拥有方,关系保存在数据库中,生成的 crud 开箱即用,但不是从反面(这是预期的: http: //docs.doctrine-project.org/en/2.0.x/参考/关联映射.html#owning-side-and-inverse-side )
我想要的是让它从反面工作,而不改变自动生成的控制器;我只想更改模型(实体)。
简单的方法是向控制器添加几个自定义代码行:
// Controller that works the way I want
// Controller/AlunoController.php
...
public function createAction(Request $request)
{
$entity = new Aluno();
$form = $this->createForm(new AlunoType(), $entity);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
// begin custom code
foreach ($entity->getResponsaveis() as $responsavel) {
$responsavel->addAluno($entity);
}
// end custom code
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('aluno_edit', array('id' => $entity->getId())));
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
...
前面的代码有效,但这不是我想要的,因为那些自定义代码行引用关系逻辑,并且应该集中在实体本身中(如果没有,它必须在更新这个的控制器中复制实体)。
因此,我接下来要做的是更改 Entity 文件中的加法器和删除器以执行所需的逻辑,添加代码以自动更新反向和拥有方(如http://docs.doctrine-project.org/中的建议) en/2.0.x/reference/association-mapping.html#picking-owning-and-inverse-side和https://stackoverflow.com/a/7045693/1501575)
// Entity/Aluno.php
...
/**
* Add responsaveis
*
* @param \MyBundle\Entity\Responsavel $responsaveis
* @return Aluno
*/
public function addResponsavei(\MyBundle\Entity\Responsavel $responsaveis)
{
/* begin custom code */
//var_dump('addResponsavei');
$responsavel->addAluno($this);
/* end custom code */
$this->responsaveis[] = $responsaveis;
return $this;
}
...
这应该有效,因为当控制器中有相同的代码时它确实有效,但实际上却没有。
问题是在控制器中运行Aluno##addResponsavei()
时永远不会调用该方法$form->bind($request)
(那里的第一个代码示例)(我通过 var_dump() 行实现了这一点。我还将 var_dumps 放在其他一些 getter 中,并且那些其他方法被称为普通的)。
所以,所有的常规 setter 确实都被调用 inside $form->bind($request)
,但不是这个。这很奇怪,因为方法名称是由 `doctrine:generate:entities' 自动生成的,我认为这会使 $form->bind() 知道如何调用所有的 setter、getter 和 adders。
问题
为什么 $form->bind() 不调用加法器方法 (Aluno##addResponsavei())?
是否有不遵循的特殊命名约定doctrine:generate:crud
阻止该方法被找到和执行?
解决方案
感谢 user1452962 的评论以及后来 Elnur Abdurrakhimov 的回答,我已经开始工作了,它实际上非常简单。
我所要做的就是在持有关系反面的属性中将选项'by_reference'添加为false,然后突然addResponsavei()
开始被调用。
// Form/AlunoType.php
...
$builder
->add('nome')
->add('cidade_natal')
->add('nascimento')
->add('email')
->add('endereco')
->add('nome_sem_acento')
->add('data_hora_cadastro')
->add('responsaveis', null, array('by_reference' => false))
->add('turmas', null, array('by_reference' => false))
...
这样,关系逻辑就从控制器中消失了,这正是我所寻找的。谢谢你们。