3

对不起,我的英语不好,我不是母语人士。如果需要,请随时更正我的文字。

这个问题真的很简单(它在本文的末尾),但我已经写了一些研究和测试的理由。

基本原理

如果你愿意,你可以跳过这个理由,直接跳到问题本身。

我已经尝试了几个小时,试图在 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-sidehttps://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))

...

这样,关系逻辑就从控制器中消失了,这正是我所寻找的。谢谢你们。

4

1 回答 1

9

您需要将by_reference选项设置为false才能调用加法器。

于 2013-02-27T10:18:32.497 回答