Symfony2使用关系实体保持表单集合

时间:2014-05-06 16:03:08

标签: php forms entity-framework symfony

尚未通过研究找到解决此问题的方法,但我试图将两种形式保存到数据库中(嵌入/收集)。我有彼此相关的实体,我希望表单提交并将两个实体保存到数据库中。

主要实体:

/**
 * @var integer
 * @ORM\OneToMany(targetEntity="Sub", mappedBy="mainId", cascade={"persist"})
 */
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")
 * @ORM\JoinColumn(name="main_id", referencedColumnName="id")
 */
protected $main;

这是我的MainType表单:

class MainType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('dano', 'text', array(
                'label' => 'DA: ',
                'disabled' => true
            ))
        ->add('partno','text', array(
                'label' => 'Part: ',
                'disabled' => true
            ))
        ->add('batchno', 'text', array(
                'label' => 'Batch: ',
                'disabled' => true
            ))
        ->add('sub', 'collection', array('type' => new SubType()))
        ->add('submit', 'submit');
}......

我的SubType表单:

class SubType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('main_id','hidden')
        ->add('rackno','text', array(
                'label' => 'Rack No(s) '
            ))
        ->add('diecode','text', array(
                'label' => 'Die Code '
            ))
        ->add('heatcode','text', array(
                'label' => 'Heat Code '
            ))
        ->add('inqty','integer', array(
                'label' => 'Qty In '
            ))
        ->add('onhold','choice', array(
                'label' => 'Hold',
                'choices' => array(
                    '1' => 'On Hold',
                    '0' => 'Released'
                ),
                'multiple' => false,
                'expanded' => true
            ));

我的控制员:

/**
 * @param Request $request
 * @Route("/{dano}", name="subpart_part")
 */
public function submitPartByDAAction(Request $request, $dano) {
    $em = $this->getDoctrine()->getManager();

    $entity = $em->getRepository('Bundle:Main')
        ->findOneByDano($dano);

    $partno = $entity->getPartno();
    $batchno = $entity->getBatchno();
    $mainid = $entity->getId();


    $main1 = new Main();
    $main1->setDano($dano);
    $main1->setPartno($partno);
    $main1->setBatchno($batchno);

    $sub1 = new Sub();
    $sub1->setMainId($mainid);
    $main1->getSub()->add($sub1);

    $form = $this->createForm(new MainType(), $main1, array(
            'method' => 'POST'
        ));

    $form->handleRequest($request);
    if($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
            $em->persist($main1);
            $em->flush();

        return $this->redirect($this->generateUrl('subpart_home'));

    }

    return $this->render('Bundle:Parts:addparts.html.twig', array(
            'form' => $form->createView()
        ));
}

让我解释一下我在这里做了什么,起初我没有Sub的“main_id”字段(与Main的id相关)但是当我尝试持久化数据时它给了我错误:

An exception occurred while executing 'INSERT INTO sub 
(main_id, rackno, heatcode, diecode, inqty, onhold) VALUES 
(?, ?, ?, ?, ?, ?)' with params [null, "46", "eterte", "seteter", 3, 0]:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 
'main_id' cannot be null

然后我创建了一个字段“main_id”,隐藏它,通过getId()从Main获取id;并将其传递给Sub的表单的setMainId();坚持,它仍然给我相同的错误,“main_id”不能为空。

我错过了什么?谢谢!

2 个答案:

答案 0 :(得分:2)

您定义的实体是错误的。首先要了解ORM和关系的概念。您的Sub实体不需要具有整数main_id。只需将其映射到Main实体即可。您的Main实体应该看起来像

/**
 * @var Sub 
 * this value is just integer in database, but doc should point it to Sub
 * @ORM\OneToMany(targetEntity="Sub", mappedBy="mainId", cascade={"persist"})
 */
protected $sub;

public function __construct() {
    $this->sub = new ArrayCollection();
}

以及您的Sub实体

/**
 * @ORM\ManyToOne(targetEntity="Main", inversedBy="sub")
 * @ORM\JoinColumn(name="main_id", referencedColumnName="id")
 */
protected $main;

你不需要main_id。 ORM将为您处理。 MainType形式很好。只需摆脱SubType形式的main_id。

您应该按对象而不是ID来引用实体。在您的控制器中也可以使用

$sub1->setMainId($mainid);

您应该设置对象。

$sub1->setMain($main1);

答案 1 :(得分:1)

你的主要形式也有点奇怪。我不是说它无效,但你应该考虑更换这一行:

- > add('sub','collection',array('type'=> new SubType()))

有这样的事情:

- > add('sub',new SubType(),array())

如果您只有“ONE”项目,我认为这样更合适。当你想要很多物品时,你可以使用收藏品。

我建议您查看表单组件...表单如何表示为树...

除非有必要,否则永远不要创建像“main_id”这样的字段。尽量不要使用id并使用关联。