Symfony2,$ form-> bind()不调用实体的adder方法

pag*_*uca 3 many-to-many symfony doctrine-orm

我很抱歉我的英语不好,我不是母语人士.如果需要,请随时更正我的文字.

这个问题非常简单(在本文的最后),但我已经通过一些研究和测试写了一个基本原理.

合理

如果您愿意,可以跳过此基本原理并直接跳到问题本身.

我一直试图在Symfony2控制台上使用doctrine:generate:entitiesdoctrine:generate:crud在反面维持一个ManyToMany关系几个小时.

从拥有方来看,关系被保存在数据库中,生成的crud开箱即用,但不是从反面(这是预期的:http://docs.doctrine-project.org/en/2.0.x/) reference/association-mapping.html#owning-side-and-reverse-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(),
    ); 
}

...
Run Code Online (Sandbox Code Playgroud)

前面的代码可以工作,但它不是我想要的,因为那些自定义代码行引用了关系逻辑,并且应该集中在实体本身(如果不是,它必须在更新这个的所有控制器上重复实体).

因此,我接下来要做的是更改Entity文件中的加法器和删除器以执行所需的逻辑,添加代码以自动更新反向和拥有方(如http://docs.doctrine-project.org/中所建议的那样)en/2.0.x/reference/association-mapping.html#picking-owning-and-inverse-side/sf/answers/493198541/)

// 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;
}

...
Run Code Online (Sandbox Code Playgroud)

这应该可以工作,因为它在控制器中使用相同的代码时确实有效,但实际上并没有.

问题是在控制器中运行Aluno##addResponsavei()时从不调用该方法$form->bind($request)(第一个代码示例在那里)(我用var_dump()行实现了这一点.我还将var_dump放在其他一些getter中,而其他方法被调用为正常).

因此,所有常规的建立者确实被称为内部$form->bind($request),但不是这个.这很奇怪,因为方法名称是由`doctrine:generate:entities'自动生成的,我假设它会使$ form-> bind()知道如何调用所有setter,getters和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))

...
Run Code Online (Sandbox Code Playgroud)

这样,关系逻辑就从控制器中消失了,这就是我在寻找的东西.感谢你们.

Eln*_*mov 9

您需要的设置by_reference选项false为了被称为加法器.

  • @Elnur:如果只有这个答案可以在网上用大字体发布.这种非常模糊的设置可以在关系的反面保持集合时节省很多麻烦.非常感谢你. (2认同)