2016-05-27 15 views
0

私はSymfonyを初めて使用しており、このドキュメントhttp://symfony.com/doc/current/cookbook/form/form_collections.htmlに従って、基本的な埋め込みコレクションフォームを作成しています。フォームデータを保存するSymfony 2.8

ドキュメントに従ってください。タグとタスクがあります。タスクにはOneToManyのタグとの関係があり、TagにはTaskとのManyToOneの関係があります。

私はまた、queryBuilderでTaskTypeのEntityType :: classを使用して、フォーム上のデータベース内の既存のTaskエンティティの選択リストを事前に設定します。

フォームの作成が完了し、すべて正常に動作します。しかし、既存の「タスクID」を使用する代わりにフォームを送信すると、新しいIDを持ちながら同じデータを持つ新しいタスクが生成されます。この新しいタスクIDは新しいタグエンティティに割り当てられます。私は新しいタグのために既存のタスクIDを使用したいと思います。

namespace AppBundle\Entity; 

/** 
* Tag 
*/ 
class Tag 
{ 
    /** 
    * @var integer 
    */ 
    private $id; 

    /** 
    * @var string 
    */ 
    private $name; 


    /** 
    * @var \AppBundle\Entity\Task 
    */ 
    private $task; 


    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set name 
    * 
    * @param string $name 
    * 
    * @return Tag 
    */ 
    public function setName($name) 
    { 
     $this->name = $name; 

     return $this; 
    } 

    /** 
    * Get name 
    * 
    * @return string 
    */ 
    public function getName() 
    { 
     return $this->name; 
    } 


    /** 
    * Set task 
    * 
    * @param \AppBundle\Entity\Task $task 
    * 
    * @return Tag 
    */ 
    public function setTask(\AppBundle\Entity\Task $task = null) 
    { 
     $this->task = $task; 

     return $this; 
    } 

    /** 
    * Get task 
    * 
    * @return \AppBundle\Entity\Task 
    */ 
    public function getTask() 
    { 
     return $this->task; 
    } 


    public function addTask(Task $task) 
    { 

     $this->setTask($task); 
    } 
} 
Tag.php

TaskController.php

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\Response; 
use AppBundle\Entity\Task; 
use AppBundle\Entity\Tag; 
use AppBundle\Form\Type\TaskType; 


class TaskController extends Controller 
{ 
    public function newAction(Request $request) 
    { 
     $task = new Task(); 

     // dummy code - this is here just so that the Task has some tags 
     // otherwise, this isn't an interesting example 
     $tag1 = new Tag(); 
     $tag1->setName('tag1'); 

     $tag1->addTask($task); 
     $task->getTags()->add($tag1); 


     $form = $this->createForm(TaskType::class, $task); 

     $form->handleRequest($request); 

     if ($form->isValid()) { 


      $em = $this->getDoctrine()->getManager(); 
      $em->persist($task); 
      $em->flush(); 
     } 

     return $this->render('AppBundle:Task:new.html.twig', array(
      'form' => $form->createView(), 
     )); 

    } 

} 

:以下

はYAMLファイルと私のクラスであります

TagType.php

namespace AppBundle\Form\Type; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolver; 



class TagType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('name'); 
    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'AppBundle\Entity\Tag', 
     )); 
    } 

} 

Tag.orm.yml

AppBundle\Entity\Tag: 
    type: entity 
    table: null 
    repositoryClass: AppBundle\Repository\TagRepository 
    id: 
     id: 
      type: integer 
      id: true 
      generator: 
       strategy: AUTO 
    fields: 
     name: 
      type: string 
      length: 255 

    manyToOne: 
     task: 
      targetEntity: Task 
      inversedBy: tags 
      joinColumn: 
       name: task_id 
       referencedColumnName: id 
      cascade: [ persist ] 


    lifecycleCallbacks: { } 

Task.php

namespace AppBundle\Entity; 

use Doctrine\Common\Collections\ArrayCollection; 

/** 
* Task 
*/ 
class Task 
{ 
    /** 
    * @var integer 
    */ 
    private $id; 

    /** 
    * @var string 
    */ 
    private $description; 

    /** 
    * @var ArrayCollection 
    */ 
    protected $tags; 


    public function __construct() 
    { 
     $this->tags = new ArrayCollection(); 
    } 

    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set description 
    * 
    * @param string $description 
    * 
    * @return Task 
    */ 
    public function setDescription($description) 
    { 
     $this->description = $description; 

     return $this; 
    } 

    /** 
    * Get description 
    * 
    * @return string 
    */ 
    public function getDescription() 
    { 
     return $this->description; 
    } 

    /** 
    * Get tags 
    * 
    * @return ArrayCollection 
    */ 
    public function getTags() 
    { 
     return $this->tags; 
    } 

    public function addTag(Tag $tag) 
    { 
     $tag->addTask($this); 
     $this->tags->add($tag); 
    } 


    /** 
    * Remove tag 
    * 
    * @param \AppBundle\Entity\Tag $tag 
    */ 
    public function removeTag(\AppBundle\Entity\Tag $tag) 
    { 
     $this->tags->removeElement($tag); 
    } 


    public function __toString() 
    { 
     return (string) $this->getDescription(); 
    } 


} 

TaskType.php

namespace AppBundle\Form\Type; 


use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolver; 
use Symfony\Component\Form\Extension\Core\Type\CollectionType; 
use Symfony\Component\Form\Extension\Core\Type\SubmitType; 
use Symfony\Bridge\Doctrine\Form\Type\EntityType; 
use Doctrine\ORM\EntityRepository; 



class TaskType extends AbstractType 
{ 
    function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('description', EntityType::class,array(
      'class' => 'AppBundle:Task', 
      'query_builder' => function (EntityRepository $er) { 
       return $er->createQueryBuilder('d'); 
      },)); 

     $builder->add('tags', CollectionType::class, array(
      'entry_type' => TagType::class, 
      'allow_add' => true, 
      'by_reference' => false, 
     )); 

     $builder->add('save', SubmitType::class, array('label' => 'Save')); 

    } 


    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'AppBundle\Entity\Task', 
     )); 
    } 

} 

Task.orm.yaml

AppBundle\Entity\Task: 
    type: entity 
    table: null 
    repositoryClass: AppBundle\Repository\TaskRepository 
    id: 
     id: 
      type: integer 
      id: true 
      generator: 
       strategy: AUTO 
    fields: 
     description: 
      type: string 
      length: 255 

    oneToMany: 
     tags: 
      targetEntity: Tag 
      mappedBy: task 
      cascade: [ persist ] 

    lifecycleCallbacks: { } 
+0

私は$ Ta​​sk = new Task();で新しいTaskを作成していますので、もちろん新しいTaskが作成されています。あなたは 'editAction'の作成方法を尋ねていますか? – Miro

答えて

0

ああ、私は問題を参照してください。 フォームを送信すると(タグ付きの新しいタスクが保存される)、同じフォームが表示されるため、ユーザーはこれを「編集」フォームと見なしますが、そうではありません。

これを行うにはどのように正しい方法は、ルートがタスク(例えばtask_id)を識別するためのパラメータを持っているだろうことだけが、newAction()のようになりこれ、たとえばeditAction()ため、タスクを編集するための新しいコントローラのアクションを作成することで、 $task = new Task();で新しいタスクを作成する代わりに、最初にあなたが例えば、DBからタスクをフェッチします:

$task = $this->get("doctrine")->getManager()->getRepository("AppBundle:Task")->findOneById($task_id); 

あなたも同じフォームタイプを再利用することができます。

return $this->redirectToRoute("task_edit", array("task_id" => $task->getId())); 

ので、追加のフォームを送信した後、あなたは、アクションを編集するためにリダイレクトされますので、次の時間:THEN

、あなたは、企業がこの新しいeditアクションに永続化された後、元のnewActionにリダイレクト追加しますタスクが変更され、タスクがサブミットされると、タスクは更新され、新しいタスクは作成されません。

+0

私たちの答えをありがとう。それは正確に私の質問に答えていないが、あなたの答えは私にそれを把握する方法を与えてくれました。ありがとうございました – user1139747

0

私がする必要があるのは、$ form-> getData()を使用して送信されたエンティティ(タスクとタグ)を取得し、手動でデータベースに保持することです。

if ($form->isValid()) { 
     $data = $form->getData(); 

     $description = $data->getDescription(); 

     $tags = new ArrayCollection(); 

     $tags = $data->getTags(); 

     foreach ($tags as $tag) { 
      $tag->addTask($description); 
     } 


     $em = $this->getDoctrine()->getManager(); 
     $em->persist($tag); 
     $em->flush(); 
    } 
関連する問題