2012-05-06 15 views
0

Symfony2アプリケーションには、AddressとTownという2つのエンティティがあります。 Addressエンティティには4桁の郵便番号プロパティ(「pcNum」)があり、これはTownエンティティのIDを参照します。住所には郵便番号が1つしかないため、1つの町のみを参照します(逆の場合もあります:町には郵便番号が多くなる可能性があります)。Symfony2に埋め込まれたフォームとデータベースに保存

両方のエンティティについて、私はTownTypeとAddressTypeというフォームを作成しました。ユーザーはTownを入力して保存することができます(これはうまくいきます)。 Addressエンティティのフォームにより、ユーザは郵便番号を含む住所を記入することができます。郵便番号はTownエンティティのIDにリンクされています。 Iは、AddressTypeにフォームから取得新しいアドレスエンティティを永続化しようとする

しかし、私はpc_numフィールド(エンティティでpcNum)が空であることをMySQLエラーを受け取る:

SQLSTATE [23000]:整合性制約違反:1048列「pc_numは」どういうわけか、その値がアドレスエンティティを永続化する前に失われている(これは町へのREFキーが含まれているはずアドレスエンティティのフィールドである)

nullにすることはできません。フォームのユーザー入力に関係なく、自分のコントローラーでフィールドを手動で入力すると、エラーなしで新しいアドレスを保持できます。 Townエンティティへのリンクをドロップして認識できないフォームフィールドを使用すると、郵便番号が存在する限り、エラーなしでも安全です。しかし、2つのフォームとエンティティ・アソシエーションを使用して、それを動作させることはできません。私は過去数週間にわたってさまざまなことを試みましたが、私はアイデアがありません。以下は私のコードです。何かにコメントしても、私の全体的なアプローチが間違っているかもしれません。これは私の住所エンティティである

namespace Xx\xBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\Validator\Constraints as Check; 

/** 
* 
* Xx\xBundle\Entity\Town 
* 
* @ORM\Table(name="lib_towns") 
* @ORM\Entity 
*/ 

class Town 
{ 
    #id 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer", length="4", nullable=false) 
    * @ORM\GeneratedValue(strategy="AUTO") 
    * @Check\NotBlank() 
    * @Check\MaxLength(4) 
    */ 
    protected $id; 

    #name 
    /** 
    * @ORM\Column(name="name", type="string", length="100", nullable=true) 
* @Check\NotBlank() 
    * @Check\MaxLength(100) 
    */ 
    protected $name; 

    //some more properties 

    #getters and setters 

    /** 
    * Set id 
    * 
    * @param integer $id 
    */ 
    public function setId($id) 
    { 
     $this->id = $id; 
    } 

    /** 
    * Get id 
    * 
    * @return integer $id 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set name 
    * 
    * @param string $name 
    */ 
    public function setName($name) 
    { 
     $this->name = $name; 
    } 

    /** 
    * Get name 
    * 
    * @return string $name 
    */ 
    public function getName() 
    { 
     return $this->name; 
    } 

    //some more getters ans setters 

} 

この

は私の町のエンティティである

namespace Xx\xBundle\Form\Type; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilder; 
use Doctrine\ORM\EntityRepository; 

class AddressType extends AbstractType 
{ 
    public function buildForm(Formbuilder $builder, array $options) 
    { 
     $builder->add('id', 'hidden'); //necessary for updates 
     $builder->add('town', 'entity', array 
      (
       'label' => 'Postal code (4 digits):*', 
       'class' => 'XxxBundle:Town', 
       'query_builder' => function(EntityRepository $er) { 
     return $er->createQueryBuilder('t') 
      ->orderBy('t.id', 'ASC'); },    
       //'empty_value' => '----', 
       'property'=> 'Id', 
       'property_path'=> false, 
       'expanded' => false, 
       'multiple' => false, 
       'required' => true 
      )); 
     $builder->add('street', 'text', array 
      (
       'label' => 'Street:*', 
       'required' => true 
      )); 
     //some more fields... 
    } 

    public function getDefaultOptions(array $options) 
    { 
     return array(
      'data_class' => 'Xx\xBundle\Entity\Address' 
     ); 
    } 

    public function getName() 
    { 
     return 'address'; 
    } 
} 

namespace Xx\xBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\Validator\Constraints as Check; 
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; 
use Xx\xBundle\Entity\Town; 

/** 
* 
* Xx\xBundle\Entity\Address 
* 
* @ORM\Entity 
* @ORM\Table(name="addresses") 
*/ 

class Address 
{ 
    #id 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer", length="6", nullable=false) 
    * @ORM\GeneratedValue(strategy="AUTO") 
* @Check\NotBlank() 
* @Check\MaxLength(6) 
    */ 
    protected $id; 

    #town 
    /** 
    * @orm\OneToOne(targetEntity="town") 
* @ORM\JoinColumn(name="pc_num", referencedColumnName="id", nullable=false) 
    */ 
    protected $town; 

    //some other properties... 

    #getters and setters 

    /** 
    * Set id 
    * 
    * @param integer $id 
    */ 
    public function setId($id) 
    { 
     $this->id = $id; 
    } 

    /** 
    * Get id 
    * 
    * @return integer $id 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set town entity linked to this address 
    * 
    */ 
    public function setTown(town $town = null) 
    { 
     $this->town = $town; 
    } 

    /** 
    * Get town entity linked to this address 
    * 
    */ 
    public function getTown() 
    { 
     return $this->town; 
    } 

    //some other functions... 

} 

次に、これは私が住所のために作成したフォームであります

これは私のアドレスコントローラの関連するアクション機能です:

あなたは、関連する(作業)の例をご存知の場合

<form action="{{ path('addAddress') }}" method="post" {{ form_enctype(form) }}> 
     {{ form_errors(form) }} 
     <div class="form_row"> 
     {{ form_errors(form.town) }} 
     {{ form_label(form.town, 'Postal code:*') }} 
     {{ form_widget(form.town, {'attr': { 'class': 'form_pcNum', 'maxlength': '4', 'size': '4' } }) }} 
     </div> 
     <div class="form_row"> 
     <!-- some more fields here --> 
     </div> 
     <div class="form_row"> 
     <button name="btn_add" id="do_add" type="submit" class="" value="btn_add" title="Ok!">Ok</button> 
     </div> 
     {{ form_rest(form) }} 
    </form> 

すべてのヘルプは高く評価され... が、それはまた、素晴らしいことだ:締結する

public function editAddressAction($id = null) 
{ 
$em = $this->getDoctrine()->getEntityManager(); 
$address = new Address(); 
$isNew = is_null($id); 
    //this also tests positve after a form has been sent 
    if($isNew) 
    { 
      #fill address object with some defaults 
      $address->setCreated(new \DateTime("now")); 
     } else 
     { 
      #fill address object with existing db data 
      $address = $em->getRepository('XxxBundle:Address')->find($id); 
     } 
     #create form and fill it with address object data 
     $form = $this->createForm(new AddressType(), $address); 
      #if form sent: check input 
      $request = $this->get('request'); 
      if ($request->getMethod() == 'POST') 
      { 
       $form->bindRequest($request); //calls setters 
       if ($form->isValid()) 
       { 
        //if I leave the following lines in: no error (but also no sense) 
        //because the pcNum should be retrieved from the form 
        $pcNum = 2222; 
        $town = $em->getRepository('XxxBundle:Town')->find($pcNum); 
        $address->setTown($town); 
        //end 

        #persist and flush 

        $id_unknown = is_null($address->getId()); 
        if($id_unknown) 
        { 
         #insert address 
         $em->persist($address); 
        } else 
        { 
         #update address 
         $address->setModified(new \DateTime("now")); 
         $em->merge($address); 
        } 
        #commit 
        $em->flush(); 
        #get id of update or insert and redirect user 
        $address_id = $address->getId(); 
        return $this->redirect($this->generateUrl('displayAddress', array('id'=>$address_id))); 
       } 
      } 
     return $this->render('XxxBundle:Forms:address.html.twig', array('form'=>$form->createView(), 'new' => $isNew, 'id' => $id)); 
    } 

が、これは、関連する小枝スニペットです。乾杯!

答えて

関連する問題