[英]Symfony & Doctrine: persisting a many to one entity on an embedded form collection
目前有點泡菜。 我有2個實體:Main和Sub,這是一個OneToMany關系(一個Main可以有很多sub),我收集了一組嵌入在一起的表單。 我首先有一個搜索表單,用戶可以通過它的一個屬性搜索Main,然后將其發送到一個頁面,在該頁面上有一個帶有搜索的Main的表單,表單上列出了其屬性,但是被禁用,因此用戶無法編輯它們,並且啟用的字段來自嵌入的Sub表單,用戶需要輸入該表單進行提交。
1)用戶通過其屬性(即“ pono”(PO編號))搜索Main
2)用戶被重定向到一個頁面,該頁面顯示了他/她使用列出的(pono),(cano)和(bano)搜索的行-已被禁用,因此無法進行編輯3)Enabled字段為空,用戶必須輸入將要提交到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()));
}
在我的Sub表單中:
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
$mainid = $entity->getId();
並將其放入$sub->setMainId($mainid)
,我不斷收到錯誤消息main_id
不能為null。
有參加者嗎? 編輯:樹枝模板:
{{ 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實體中(添加級聯持續)
/**
* @var Sub
* @ORM\OneToMany(targetEntity="Sub", mappedBy="main", cascade={"persist"})
*/
protected $sub;
2)SUB實體:
刪除受保護的$ mainId; 它是注釋。
從ManyToOne移除級聯= {“ 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()返回collection,而前兩個將返回$ this。
5)控制器
不保留Sub,而是Main。 (Doctrine將級聯持久化到Sub)
$em->persist($main);
6)您需要在主表單類型內部的子集合中添加“ by_reference”選項。
->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定義為唯一。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.