目前有点麻烦。我有2个实体:主和子,这是一个onetmany关系(一个主可以有许多子)我做了一个集合的形式嵌入在一起。我首先有一个搜索表单,其中用户可以通过其属性之一搜索Main,然后它将它们发送到一个页面,其中有一个包含搜索Main的表单,其属性在表单上列出,但被禁用,因此用户无法编辑它们,并且启用的字段来自用户需要输入提交的嵌入式Sub表单。
1)用户通过其属性搜索Main,即" PO " (PO号)
2)用户被重定向到一个页面,该页面显示了他/她搜索的行,并列出了(pono), (cano), (bano) -它被禁用,因此无法编辑3) Enabled字段为空,用户必须输入将提交到Sub实体的信息。
在我的主实体
/**
* @var Sub
* @ORM'OneToMany(targetEntity="Sub", mappedBy="mainId")
*/
protected $sub;
public function __construct() {
$this->sub = new ArrayCollection();
}
和我的子实体:
/**
* @var integer
*
* @ORM'Column(name="main_id", type="integer")
*/
protected $mainId;
/**
* @ORM'ManyToOne(targetEntity="Main", inversedBy="sub", cascade={"persist"})
* @ORM'JoinColumn(name="main_id", referencedColumnName="id")
*/
protected $main;
In my Main form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('pono', 'text', array(
'label' => 'PO: ',
'disabled' => true
))
->add('cano','text', array(
'label' => 'CA: ',
'disabled' => true
))
->add('bano', 'text', array(
'label' => 'BA: ',
'disabled' => true
))
->add('sub', 'collection', array('type' => new SubType()));
}
在我的子窗体中:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('qty','integer', array(
'label' => 'Qty: '
))
->add('location','text', array(
'label' => 'Location: '
))
->add('priority','text', array(
'label' => 'Priority: '
));
}
在我的控制器
public function submitItemAction(Request $request, $pono) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ItemBundle:Main')
->findOneByPono($pono);
$cano = $entity->getCano();
$bano = $entity->getBano();
$main = new Main();
$main->setPono($pono);
$main->setCano($cano);
$main->setBano($bano);
$sub = new Sub();
$sub->setMain($main);
$main->getSub()->add($sub);
$form = $this->createForm(new MainType(), $main, array(
'method' => 'POST'
))
->add('submit','submit');
$form->handleRequest($request);
if($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($sub);
$em->flush();
return $this->redirect($this->generateUrl('success'));
}
现在提交时,它同时提交了Main和Sub。它给了我一个重复的Main和新添加的Sub。我知道这是它应该做的,但我需要它只提交Sub。我试着用$mainid = $entity->getId();
从Main检索id
并将其放入$sub->setMainId($mainid)
,我不断得到main_id
不能为空的错误信息。
人吗?编辑:小树枝模板:
{{ form_start(form) }}
{{ form_label(form.pono) }}
{{ form_widget(form.pono) }} <br>
{{ form_label(form.cano) }}
{{ form_widget(form.cano) }}<br>
{{ form_label(form.bano) }}
{{ form_widget(form.bano) }} <br>
{% for sub in form.sub %}
{{ form_label(sub.qty) }}
{{ form_widget(sub.qty) }} <br>
{{ form_label(sub.location) }}
{{ form_widget(sub.location) }} <br>
{{ form_label(sub.priority) }}
{{ form_widget(sub.priority) }}<br>
{% endfor %}
{{ form_widget(form.submit) }}
{{ form_end(form) }}
看了你的代码后,我认为有可能使它工作,有一些事情你需要修复。我将在几个步骤中编辑这个答案。在你开始修改之前,也要备份/提交你的代码。
1)在你的MAIN实体中(添加cascade持久化)
/**
* @var Sub
* @ORM'OneToMany(targetEntity="Sub", mappedBy="main", cascade={"persist"})
*/
protected $sub;
2)子实体:
删除受保护的$mainId;它是annotation
从ManyToOne中删除cascade={"persist"}
3)看你的控制器动作
$sub = new Sub();
$sub->setMain($main);
$main->getSub()->add($sub);
注意setMain()方法。你不希望在控制器中这样做,而希望在实体中自动这样做。你也应该手动添加到集合中,但是要为它创建一个方法。所以你只有这个:
$sub = new Sub();
$main->addSub($sub);
4)在MAIN实体添加(您可能需要导入Sub):
public function addSub(Sub $sub) {
$sub->setMain($this);
$this->sub->add($sub);
return $this;
}
您还应该添加其他方法,如removeSub(), removeSub(), getSub()。getSub()返回集合,而前两个返回$this。
5)控制器不要保存Sub,而是保存Main。(原则级联持久性到子级)
$em->persist($main);
6)你需要添加'by_reference'选项的子集合在你的主表单类型。
->add('sub', 'collection', array('type' => new SubType(), 'by_reference' => false));
这将调用实际的addSub()方法,而不是直接调用add方法。
7)我不知道你为什么在下面新建一个Main实体。
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ItemBundle:Main')
->findOneByPono($pono);
$cano = $entity->getCano();
$bano = $entity->getBano();
$main = new Main();
$main->setPono($pono);
$main->setCano($cano);
$main->setBano($bano);
尝试更改为:
$em = $this->getDoctrine()->getManager();
$main = $em->getRepository('ItemBundle:Main')
->findOneByPono($pono);
您可能应该将Pono定义为唯一的