【发布时间】:2015-09-29 19:12:39
【问题描述】:
我按照here 的文档进行了操作:但无法将示例持久保存到嵌入式表单的数据库中; Plant 类保存得很好。我假设控制器中的持久化和刷新方法处理两个实体的持久化。这是错误的假设吗?是否需要在flush前拦截并在控制器中手动设置?
无论如何,这是我的代码:
Plant Entity:
<?php
/**
* @ORM\Entity(repositoryClass="Blogger\BlogBundle\Entity\Repository\PlantRepository")
* @ORM\Table(name="plant")
* @ORM\HasLifecycleCallbacks
*/
class Plant
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="array", nullable=true)
* @ORM\ManyToMany(targetEntity="Blogger\BlogBundle\Entity\Picture", inversedBy="plants", cascade={"persist"})
* @ORM\JoinTable(name="picture")
*/
protected $pictures;
//...
public function __construct()
{
$this->pictures = new ArrayCollection;
}
//...
/**
* Add pictures
*
* @param \Blogger\BlogBundle\Entity\Picture $pictures
* @return Plant
*/
public function addPicture(\Blogger\BlogBundle\Entity\Picture $pictures)
{
$pictures->addPlant($this);
$this->pictures[] = $pictures;
}
/**
* Remove pictures
*
* @param \Blogger\BlogBundle\Entity\Picture $pictures
*/
public function removePicture(\Blogger\BlogBundle\Entity\Picture $pictures)
{
$this->pictures->removeElement($pictures);
}
/**
* Get pictures
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getPictures()
{
return $this->pictures;
}
}
图片实体:
<?php
namespace Blogger\BlogBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="Picture")
*/
class Picture
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
//...
/**
* @ORM\Column(type="text")
*/
public $path;
/**
* @ORM\Column(type="array", nullable=true)
* @ORM\ManyToMany(targetEntity="Blogger\BlogBundle\Entity\Plant", mappedBy="pictures")
*/
private $plants;
/**
* Constructor
*/
public function __construct()
{
$this->plants = new \Doctrine\Common\Collections\ArrayCollection();
}
//...
/**
* Set path
*
* @param string $path
* @return Picture
*/
public function setPath($path)
{
$this->path = $path;
return $this;
}
/**
* Get path
*
* @return string
*/
public function getPath()
{
return $this->path;
}
/**
* Add plants
*
* @param \Blogger\BlogBundle\Entity\Plant $plants
* @return Picture
*/
public function addPlant(\Blogger\BlogBundle\Entity\Plant $plants)
{
if (!$this->plants->contains($plants)) {
$this->plants->add($plants);
}
}
/**
* Remove plants
*
* @param \Blogger\BlogBundle\Entity\Plant $plants
*/
public function removePlant(\Blogger\BlogBundle\Entity\Plant $plants)
{
$this->plants->removeElement($plants);
}
/**
* Get plants
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getPlants()
{
return $this->plants;
}
}
植物形态:
<?php
namespace Blogger\BlogBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class PlantForm extends AbstractType
{
public function __construct($em) {
$this->em = $em;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
//...
$builder->add('pictures', 'collection', array(
'type' => new PictureForm(),
'options' => array(
'data_class' => 'Blogger\BlogBundle\Entity\Picture'),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Blogger\BlogBundle\Entity\Plant',
));
}
public function getName()
{
return 'plant';
}
}
图片形式:
<?php
namespace Blogger\BlogBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class PictureForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
//...
$builder->add('path', 'textarea');
//...
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Blogger\BlogBundle\Entity\Picture',
));
}
public function getName()
{
return 'picture';
}
}
工厂控制器:
public function newAction(Request $request){
$plant = new Plant();
$image1 = new Picture();
$plant->getPictures()->add($image1);
$form = $this->createForm(new PlantForm($this->getDoctrine()->getManager()), $plant);
if ($request->getMethod() == 'POST') {
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()
->getEntityManager();
$em->persist($plant);
$em->flush();
return $this->redirect($this->generateUrl('route', array(
'id' => $plant->getId()
)));
}
}
return $this->render('Bundle:Plant:new.html.twig', array(
'form' => $form->createView()
));
}
我怀疑我没有正确映射数据库的注释。当我打开 phpadmin 时,数据库中没有定义任何关系。
【问题讨论】:
-
在持久化植物之后添加这段代码并测试它:
$em->persist($image1),也许它可以工作 -
这确实有效,但我忽略了取出 $image1 虚拟数据(一开始就不应该存在)。我已经这样做了,当图片被动态添加到表单时,它现在不会保留图片。植物中的图片字段实际上是在持久化整个植物对象......包括动态添加的图片。这是有道理的。它被映射为一个数组。这些字段应该映射为什么?将它们留空会导致错误。
标签: symfony doctrine-orm