[英]Persist form data Symfony 2.8
我是Symfony的新手,並且遵循此文檔http://symfony.com/doc/current/cookbook/form/form_collections.html來構建基本的嵌入收集表單。
請遵循文檔。 我們有標簽和任務。 Task與Tag具有oneToMany關系,而Tag與Task具有ManyToOne關系。
我還將TaskType中的EntityType :: class與queryBuilder一起使用,以在表單上的數據庫中預先填充現有Task實體的選擇列表。
我已經完成了構建表格,一切正常。 但是,當我提交表單而不使用現有的“任務ID”時,會生成一個具有新ID但具有相同數據的新任務。 該新任務ID被分配給新的標簽實體。 我想將現有的任務ID用於新標簽。
以下是我的YAML文件類:
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(),
));
}
}
Tag.php
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);
}
}
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',
));
}
}
標記文件
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: { }
哦,我明白了。 提交表單(並保存帶有標簽的新任務)時,將顯示相同的表單,因此用戶希望它是“編輯”表單,但事實並非如此。
正確的方法是創建新的控制器動作來編輯任務,例如editAction()
,它類似於newAction()
,只是路由將具有用於標識任務的參數(例如task_id
),並且首先不要用$task = new Task();
創建新Task $task = new Task();
您可以從數據庫中獲取任務,例如:
$task = $this->get("doctrine")->getManager()->getRepository("AppBundle:Task")->findOneById($task_id);
您也可以重復使用相同的表單類型。
然后 ,您將實體保留到此新的編輯操作后,在原始newAction中添加重定向:
return $this->redirectToRoute("task_edit", array("task_id" => $task->getId()));
因此,在提交添加表單后,您將被重定向到編輯操作,因此下次更改任務並提交時,該任務將更新而不創建新任務。
因此,我需要做的是使用$ 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();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.