英語が下手で申し訳ありません。私はネイティブ スピーカーではありません。必要に応じて、テキストを自由に修正してください。
質問は非常に単純ですが (このテキストの最後にあります)、いくつかの調査とテストを行ってその根拠を書きました。
根拠
必要に応じて、この理論的根拠をスキップして、質問自体に直接ジャンプできます。
私は、Symfony2コンソールを使用doctrine:generate:entities
して、逆側からManyToMany関係を維持しようと数時間試みてきました。doctrine:generate:crud
所有側からは、生成されたクラッドをそのまま使用して関係がデータベースに保存されますが、逆側からではありません (これは期待されます: http://docs.doctrine-project.org/en/2.0.x/ reference/association-mapping.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(),
);
}
...
前のコードは機能しますが、これらのコードのカスタム行は関係ロジックを参照し、エンティティ自体に集中する必要があるため、これは私が望むものではありません (そうでない場合は、これを更新するコントローラー全体に複製する必要があります)実在物)。
そこで、私が次に行ったことは、必要なロジックを実行するためにエンティティ ファイルのアダーとリムーバーを変更し、逆側と所有側の両方を自動的に更新するコードを追加することでした ( 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 を配置し、それらの他のメソッドは次のように呼び出されました)。正常)。
したがって、すべての通常のセッターは確かに内部$form->bind($request)
で呼び出されますが、これはそうではありません。メソッド名は `doctrine:generate:entities' によって自動生成されたので、これは奇妙です。これにより、$form->bind() はすべてのセッター、ゲッター、およびアダーを呼び出す方法を知ることができると思いました。
質問
$form->bind() が adder メソッド (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))
...
このようにして、コントローラーから関係ロジックがなくなり、それが私が探していたものです。君たちありがとう。