2014-06-29 30 views
0

我可以讓用戶在一個單一的形式,而不是具有兩種不同的形式但是我得到的品牌已經在數據庫中存在的錯誤消息「堅持BrandsCars數據。「對於那些已經存在於Brands表中的品牌。它應該如何工作的是:如果品牌名稱已經存在,則不要嘗試再次保留它,因爲name字段在數據庫中被標記爲唯一。我該如何解決這個問題?無法因爲唯一性約束將持續1-N

備註:我之所以有兩種額外的表單類型,是因爲我也有兩個不同的接口來分別收集品牌和汽車數據。

CONTROLLER

public function createAction(Request $request) 
{ 
    if ($request->getMethod() != 'POST') 
    { 
     return new Response('Only POST method is allowed'); 
    } 

    $form = return $this->createForm(new BothType(), null, 
      array('action' => $this->generateUrl('bothCreate'))); 

    $form->handleRequest($request); 

    if ($form->isValid()) 
    { 
     $brandsData = $form->get('brands')->getData(); 
     $carsData = $form->get('cars')->getData(); 

     $brands = new Brands(); 
     $brands->setName($brandsData->getName()); 

     $cars = new Cars(); 
     $cars->setModel($carsData->getModel()); 
     $cars->setBrands($brands); 

     $em = $this->getDoctrine()->getManager(); 
     $em->persist($brands); 
     $em->persist($cars); 
     $em->flush(); 

     return $this->redirect($this->generateUrl('both')); 
    } 

    return $this->render('CarBrandBundle:Default:both.html.twig', 
      array('page' => 'Both', 'form' => $form->createView())); 
} 

BOTH TYPE

class BothType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->setMethod('POST') 
      ->setAction($options['action']) 
      ->add('brands', new BrandsType()) 
      ->add('cars', new CarsType()) 
      ->add('button', 'submit', array('label' => 'Add')) 
      ; 
    } 
} 

BRANDS ENTITY

/** 
* @ORM\Entity 
* @ORM\Table(name="brands", uniqueConstraints={@ORM\UniqueConstraint(columns={"name"})}) 
* @UniqueEntity(fields="name", message="The Brand already exist in database.") 
* @package Car\BrandBundle\Entity 
*/ 
class Brands 
{ 
    protected $id; 
    protected $name; 

    /** 
    * @ORM\OneToMany(targetEntity="Cars", mappedBy="brands") 
    */ 
    protected $cars; 

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

    public function getId() { return $this->id; } 
    public function setName($name) { $this->name = $name; return $this; } 
    public function getName() { return $this->name; } 

    public function addCar(\Car\BrandBundle\Entity\Cars $cars) 
    { 
     $this->cars[] = $cars; 
     return $this; 
    } 

    public function removeCar(\Car\BrandBundle\Entity\Cars $cars) 
    { 
     $this->cars->removeElement($cars); 
    } 

    public function getCars() 
    { 
     return $this->cars; 
    } 
} 

BRANDS TYPE

class BrandsType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->setAction($options['action']) 
      ->setMethod('POST') 
      ->add('name', 'text', array('label' => 'Name')) 
      ->add('button', 'submit', array('label' => 'Add')) 
     ; 
    } 
} 

CARS ENTITY

class Cars 
{ 
    protected $id; 
    protected $model; 

    /** 
    * @ORM\ManyToOne(targetEntity="Brands", inversedBy="cars") 
    * @ORM\JoinColumn(name="brands_id", referencedColumnName="id", nullable=false) 
    */ 
    protected $brands; 

    public function getId() { return $this->id; } 
    public function setModel($model) { $this->model = $model; return $this; } 
    public function getModel() { return $this->model; } 

    public function setBrands(\Car\BrandBundle\Entity\Brands $brands = null) 
    { 
     $this->brands = $brands; 
     return $this; 
    } 

    public function getBrands() 
    { 
     return $this->brands; 
    } 
} 

CARS TYPE

class CarsType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->setAction($options['action']) 
      ->setMethod('POST') 
      ->add('model', 'text', array('label' => 'Model')) 
      ->add('price', 'text', array('label' => 'Price')) 
      ->add('button', 'submit', array('label' => 'Add')) 
     ; 
    } 
} 

回答

0

通過使用未映射到數據庫,這樣我可以忽略唯一形式模型解決檢查是哪個導致了整個問題。

創建一個名爲BothModel新模式,即沒有映射到數據庫:

class BothModel 
{ 
    /** 
    * @Assert\NotBlank(message="The Name field should not be blank") 
    */ 
    protected $name; 

    /** 
    * @Assert\NotNull(message="The Origin field should not be blank") 
    */ 
    protected $origin; 

    /** 
    * @Assert\NotNull(message="The Model field should not be blank") 
    */ 
    protected $model; 

    /** 
    * @Assert\NotNull(message="The Price field should not be blank") 
    */ 
    protected $price; 


    public function setName($name) 
    { 
     $this->name = $name; 
     return $this; 
    } 

    public function getName() 
    { 
     return $this->name; 
    } 

    public function setOrigin($origin) 
    { 
     $this->origin = $origin; 
     return $this; 
    } 

    public function getOrigin() 
    { 
     return $this->origin; 
    } 

    public function setModel($model) 
    { 
     $this->model = $model; 
     return $this; 
    } 

    public function getModel() 
    { 
     return $this->model; 
    } 

    public function setPrice($price) 
    { 
     $this->price = $price; 
     return $this; 
    } 

    public function getPrice() 
    { 
     return $this->price; 
    } 
} 

2.更新BothType並添加表單域單獨,而不是發起品牌和汽車表單類型。

class BothType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->setMethod('POST') 
      ->setAction($options['action']) 
      ->add('name', 'text', array('label' => 'Name')) 
      ->add('origin', 'text', array('label' => 'Origin')) 
      ->add('model', 'text', array('label' => 'Model')) 
      ->add('price', 'text', array('label' => 'Price')) 
      ->add('button', 'submit', array('label' => 'Add')) 
      ; 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array('data_class' => 'Car\BrandBundle\Form\Model\BothModel')); 
    } 

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

3.更新所述控制器相應地:

public function createAction(Request $request) 
{ 
    if ($request->getMethod() != 'POST') 
    { 
     return new Response('Only POST method is allowed'); 
    } 

    $form = $this->createForm(new BothType(), new BothModel(), 
      array('action' => $this->generateUrl('bothCreate'))); 

    $form->handleRequest($request); 

    if ($form->isValid()) 
    { 
     $submission = $form->getData(); 

     $repo = $this->getDoctrine()->getRepository('CarBrandBundle:Brands'); 
     $brands = $repo->findOneBy(array('name' => $submission->getName())); 

     if (! $brands) 
     { 
      $brands = new Brands(); 
      $brands->setName($submission->getName()); 
      $brands->setOrigin($submission->getOrigin()); 
     } 

     $cars = new Cars(); 
     $cars->setModel($submission->getModel()); 
     $cars->setPrice($submission->getPrice()); 
     $cars->setBrands($brands); 

     $em = $this->getDoctrine()->getManager(); 
     $em->persist($brands); 
     $em->persist($cars); 
     $em->flush(); 

     //return new Response('Brands ID: ' . $brands->getId() . ' - Cars ID: ' . $cars->getId()); 

     return $this->redirect($this->generateUrl('both')); 
    } 

    return $this->render('CarBrandBundle:Default:both.html.twig', 
      array('page' => 'Both', 'form' => $form->createView())); 
}