为了简化,我有两个实体。一个是产品,第二个是属性。产品实体与属性有一个OneToMany关系,而属性已经有了ManyToOne到产品(所以这是OneToMany双向关系)。我已经使用CRUD创建了表单并在ProductType中添加了集合,因此在一个页面上我可以例如为产品编辑一个assign属性。问题是,当我单击“更新”时,它会将行插入属性表,值列正常,但product_id列为空。有人可以帮帮我吗?
产品实体:
/**
* Product
*
* @ORM\Table(name="product")
* @ORM\Entity
*/
class Product
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
...
...
...
/**
* @ORM\OneToMany(targetEntity="Attribute", mappedBy="product", cascade={"persist", "remove"})
*/
private $attribute;
/**
* Constructor
*/
public function __construct()
{
$this->attribute = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add attribute
*
* @param \ePOS\ProductsBundle\Entity\Attribute $attribute
* @return Product
*/
public function addAttribute(\ePOS\ProductsBundle\Entity\Attribute $attribute)
{
$this->attribute[] = $attribute;
return $this;
}
/**
* Remove attribute
*
* @param \ePOS\ProductsBundle\Entity\Attribute $attribute
*/
public function removeAttribute(\ePOS\ProductsBundle\Entity\Attribute $attribute)
{
$this->attribute->removeElement($attribute);
}
/**
* Get attribute
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getAttribute()
{
return $this->attribute;
}
}
属性实体:
/**
* Attribute
*
* @ORM\Table(name="product_attribute")
* @ORM\Entity
*/
class Attribute
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="value", type="string", length=255)
*/
private $value;
/**
* @ORM\ManyToOne(targetEntity="Product", inversedBy="attribute")
* @ORM\JoinColumn(name="product_id", referencedColumnName="id")
**/
private $product;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set value
*
* @param string $value
* @return Attribute
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* Get value
*
* @return string
*/
public function getValue()
{
return $this->value;
}
/**
* Set product
*
* @param \ePOS\ProductsBundle\Entity\Product $product
* @return Attribute
*/
public function setProduct(\ePOS\ProductsBundle\Entity\Product $product = null)
{
$this->product = $product;
return $this;
}
/**
* Get product
*
* @return \ePOS\ProductsBundle\Entity\Product
*/
public function getProduct()
{
return $this->product;
}
}
产品型号:
class ProductType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('attribute', 'collection', array(
'type' => new AttributeType(),
'allow_add' => true,
'prototype' => true,
'prototype_name' => 'attribute__name__'
))
;
}
...
...
}
属性类型:
class AttributeType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('value')
;
}
...
...
}
ProductController的:
/**
* Product controller.
*
* @Route("/product")
*/
class ProductController extends Controller
{
...
...
/**
* Displays a form to edit an existing Product entity.
*
* @Route("/{id}/edit", name="products_product_edit")
* @Method("GET")
* @Template()
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ePOSProductsBundle:Product')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Product entity.');
}
$editForm = $this->createEditForm($entity);
$deleteForm = $this->createDeleteForm($id);
return array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
);
}
/**
* Creates a form to edit a Product entity.
*
* @param Product $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Product $entity)
{
$form = $this->createForm(new ProductType(), $entity, array(
'action' => $this->generateUrl('products_product_update', array('id' => $entity->getId())),
'method' => 'PUT',
));
$form->add('submit', 'submit', array('label' => 'Update'));
return $form;
}
/**
* Edits an existing Product entity.
*
* @Route("/{id}", name="products_product_update")
* @Method("PUT")
* @Template("ePOSProductsBundle:Product:edit.html.twig")
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ePOSProductsBundle:Product')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Product entity.');
}
$deleteForm = $this->createDeleteForm($id);
$editForm = $this->createEditForm($entity);
$editForm->handleRequest($request);
if ($editForm->isValid()) {
$em->flush();
return $this->redirect($this->generateUrl('products_product_edit', array('id' => $id)));
}
return array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
);
}
...
...
}
编辑(临时解决方案):
我发现当我使用属性保存产品时,它没有运行setAttribute函数。所以我所做的是在函数createEditForm中进行一些更改:
ProductController的:
private function createEditForm(Product $entity)
{
$data = $this->get('request')->request->get('epos_productsbundle_product');
$count = count($data['attribute']);
for($i=1; $i<=$count; $i++){
$attribute = new \ePOS\ProductsBundle\Entity\Attribute();
$attribute->setProduct($entity);
$entity->addAttribute($attribute);
}
$form = $this->createForm(new ProductType($this->get('security.context')->getToken()->getUser()->getId()), $entity, array(
'action' => $this->generateUrl('products_product_update', array('id' => $entity->getId())),
'method' => 'PUT',
));
$form->add('submit', 'submit', array('label' => 'Update'));
return $form;
}
但如果有人能够知道更好的解决方案,请告诉我。
答案 0 :(得分:3)
使用stwe的溶液与'by_reference'=&gt;结合使用集合字段上的false表单选项。 看一下'Doctrine:Cascading Relations并保存此链接中的“Inverse”side'部分:How to Embed a Collection of Forms
答案 1 :(得分:2)
您可以更改addAttribute函数,
/**
* Add attribute
*
* @param \ePOS\ProductsBundle\Entity\Attribute $attribute
* @return Product
*/
public function addAttribute(\ePOS\ProductsBundle\Entity\Attribute $attribute)
{
$attribute->setProduct($this);
$this->attribute[] = $attribute;
return $this;
}