2

私はオブジェクトを作成するためのSymfony/Doctrineアプローチに苦労し続けています。現在の問題は、多面にオブジェクトを作成せずに、1対多の片側にオブジェクトを作成するのに最適な方法です。問題は、関係の所有側である多くの側、したがってオブジェクトが永続化されるかどうかの決定要因に起因するようです。

詳細:クライアントエンティティは、メンバーエンティティと1対多の関係にあります。クライアントは、を使用して単独で作成できます

        $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())));
        }

およびクライアントと1つまたは複数のメンバー。

$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;
    }

上記のコードは、メンバーが挿入されていない場合にエラーをスローします。メンバーの有無にかかわらず、1ビットのコードでクライアントを追加できますか?

4

2 に答える 2

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->('メンバー' ...

メンバーセレクターをフォームに提供し、カスケード永続化は他のすべてを処理する必要があります。メンバーをエンティティ タイプとして指定し、クエリ ビルダーを介してリストを作成することができます。

于 2012-12-20T01:59:42.923 に答える
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(),
    );
于 2012-12-20T18:01:24.763 に答える