簡體   English   中英

Symfony&Doctrine:在嵌入式表單集合中保留多個實體

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM