Symfony2:插入一个没有多对多的那个

时间:2012-12-20 00:25:23

标签: symfony doctrine

我继续努力使用Symfony / Doctrine方法来创建对象。目前的问题是如何最好地在一对多的一侧创建一个对象而不在多方面创建一个对象。问题似乎源于许多方面是关系的拥有方,因此决定了对象是否持久存在。

详情:客户实体与成员实体有一对多的关系。客户端可以通过

自行创建
        $client  = new Client();
        $form = $this->createForm(new ClientType(), $client);
        $form->bind($request);
        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($client);
            $em->flush();
            return $this->redirect($this->generateUrl('client_show', array('id' => $client->getId())));
        }

和客户加上一个或多个成员,但不是单独使用

$client  = new Client();
$member = new Member();
$client->addMember($member);
$form = $this->createForm(new ClientType(), $client);
$form->bind($request);
if ($form->isValid()) {
    $em = $this->getDoctrine()->getManager();
    $member->setClient($client);
    $em->persist($member);
    $em->flush();
    return $this->redirect($this->generateUrl('client_show', array('id' => $client->getId())));

客户实体:

class Client
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
    * @ORM\OneToMany(targetEntity="Member", mappedBy="client")
    * 
    */
    protected $members;

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

    public function getMembers()
    {
        return $this->members;
    }

    public function setMembers($members)
    {
        foreach ($members as $members)
        {
            $members->addClient($this);
        }
        $this->members = $members;
        return $this;
    }

    public function addMember(Member $member)
    {
        $this->members->add($member);
//        $member->setClient($this);
        return $this;
//        $this->members[] = $member;
    }

    public function removeMember(Member $member)
    {
        $this->members->removeElement($member);
        return $this;
    } 

会员实体:

class Member 
{

    /**
     * @var integer $id
     *
     * @ORM\Column(name="hid", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

     /**
     * @ORM\ManyToOne(targetEntity="Client",inversedBy="members",cascade={"remove", "persist"})
     * @ORM\JoinColumn(name="clientId", referencedColumnName="id")
     * 
     */
     protected $client;

    public function setClient(Client $client)
    {
        $this->client = $client;
        return $this;
    }

    public function getClient()
    {
        return $this->client;
    }

如果没有插入成员,上面的代码会抛出错误。是否可以指定单个代码来添加具有或不具有成员的客户端?

2 个答案:

答案 0 :(得分:1)

Bind获取表单数据并将其写入对象,然后将其保留。

你打电话:

$client->addMember($member);

在绑定之前,基本上是向客户端添加一个空对象,这似乎不是你想要做的。事实上,我希望第一个代码正是您想要的,但您的ClientType()不合适。

我想你想要这样的东西:

<?php

namespace ormed\ormedBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class ClientType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('ClientField' // one of several, probably
                     ,null
                     ,array() // specify options
                     )
                ->add('member'
                     ,null
                     ,array()  // specify options
                     )
         ;
    }
}

添加

  

$ builder-&gt;('member'...

会将成员选择器提供给表单,然后您的级联持久化应该处理其他所有内容。您可能希望将成员指定为实体类型,并通过查询构建器构建列表。

答案 1 :(得分:1)

似乎涵盖两种情况的createAction:客户端和没有成员的客户端。

public function createAction(Request $request)
{
    $client  = new Client();
    $form = $this->createForm(new ClientType(), $client);
    $form->bind($request);
    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $members = $client->getMembers();
        foreach ($members as $member)
        {
            $member->setClient($client);
            $em->persist($member);
        }
        $em->persist($client);
        $em->flush();
        return $this->redirect($this->generateUrl('client_show', array('id' => $client->getId())));
    }        
    return array(
        'entity' => $client,
        'form'   => $form->createView(),
    );