目前有点咸菜。我有2个实体:Main和Sub,它是一个OneToMany关系(一个main可以有很多subs)我创建了一个嵌入在一起的表单集合。我首先有一个搜索表单,用户可以通过其中一个属性搜索Main,然后将它们发送到一个页面,其中有一个包含搜索到的Main的表单,其属性列在表单上但被禁用,因此用户无法编辑它们,已启用的字段来自嵌入的子表单,用户需要输入该表单才能提交。
1)用户通过其属性搜索Main,即“pono”(PO编号)
2)用户被重定向到一个页面,该页面显示他/她使用列出的(pono),(cano),(bano)搜索的行 - 它被禁用,因此无法编辑
3)启用的字段为空,用户必须输入将提交到Sub实体的信息。
在我的主要实体
/**
* @var Sub
* @ORM\OneToMany(targetEntity="Sub", mappedBy="mainId")
*/
protected $sub;
public function __construct() {
$this->sub = new ArrayCollection();
}
我的Sub实体:
/**
* @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;
以我的主要形式:
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'));
}
现在提交时,它正在提交BOTH Main和Sub。它给了我一个重复的Main和新添加的Sub。我知道这是它应该做的,但我需要它只提交Sub。我尝试使用id
从Main检索$mainid = $entity->getId();
并将其放入$sub->setMainId($mainid)
,然后我不断收到main_id
不能为空的错误消息。
任何接受者? 编辑:Twig模板:
{{ 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) }}
答案 0 :(得分:2)
在查看您的代码后,我认为可以使其工作,您需要修复一些事项。我将在几个步骤中编辑此答案。在开始更改代码之前,还要备份/提交代码。
1)在MAIN实体中(添加级联持久性)
/**
* @var Sub
* @ORM\OneToMany(targetEntity="Sub", mappedBy="main", cascade={"persist"})
*/
protected $sub;
2)SUB实体:
删除受保护的$ mainId;它的注释。
从ManyToOne
中删除cascade = {&#34; persist&#34;}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,而是坚持。 (学说将级联持续到Sub)
$em->persist($main);
6)您需要添加&#39; by_reference&#39;主要表格类型中的子集合选项。
->add('sub', 'collection', array('type' => new SubType(), 'by_reference' => false));
这将调用实际的addSub()方法,而不是直接调用add方法。
7)我不知道你为什么在下面建立一个新的主要实体。
$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定义为唯一。