2015-07-10 86 views
2

我試圖創建兩個實體之間的OneToOne無向關係。我創建了模式,但是當我提交表單時,它不會將數據保存到集合中。根據我的所有研究,我懷疑這是因爲我沒有正確設置擁有實體,但我已盡全力弄清楚它們沒有運氣。OneToOne單向收集不持久數據

實體 - Products.php(擁有方)

<?php 
    namespace SCWDesignsBundle\Entity\Products; 

    use Doctrine\ORM\Mapping as ORM; 
    use Doctrine\Common\Collections\ArrayCollection; 
    use Symfony\Component\Validator\Mapping\ClassMetaData; 
    use Symfony\Component\Validator\Constraints as Assert; 

    /** 
    * @ORM\Entity(repositoryClass="SCWDesignsBundle\Entity\Repository\Products\ProductRespository") 
    * @ORM\Table(name="products") 
    */ 
    class Products { 
     /** 
     * @ORM\ID 
     * @ORM\Column(type="integer") 
     * @ORM\GeneratedValue(strategy="AUTO") 
     */ 
     protected $id; 

     /** 
     * @ORM\ManyToOne(targetEntity="ProductCategories") 
     * @ORM\JoinColumn(name="category_id", referencedColumnName="id") 
     * @Assert\NotBlank() 
     */ 
     protected $category_id; 

     /** 
     * @ORM\Column(type="boolean", options={"default" = 0}) 
     */ 
     protected $featured; 

     /** 
     * @ORM\Column(type="boolean", options={"default" = 1}) 
     */ 
     protected $enabled; 

     /** 
     * @ORM\Column(type="boolean", options={"default" = 0}) 
     */ 
     protected $free_shipping; 

     /** 
     * @ORM\OneToOne(targetEntity="ProductSales") 
     * @ORM\JoinColumn(name="participate_sale", referencedColumnName="id") 
     */ 
     protected $participate_sale; 

     /** 
     * @ORM\Column(type="decimal") 
     */ 
     protected $price; 

     /** 
     * @ORM\Column(type="integer") 
     */ 
     protected $sku; 

     /** 
     * @ORM\Column(type="datetime") 
     */ 
     protected $arrival_date; 

     /** 
     * @ORM\Column(type="datetime") 
     */ 
     protected $update_date; 

     /* 
     * ArrayCollection for ProductDescription 
     * @ORM\OneToOne(targetEntity="ProductDescription", mappedBy="product_id", cascade={"persist"}) 
     * @ORM\JoinColumn(name="description", referencedColumnName="product_id") 
     */ 
     protected $description; 

     public function __construct() { 
      $this->setArrivalDate(new \DateTime()); 
      $this->description = new ArrayCollection(); 
     } 

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

     /** 
     * Set featured 
     * 
     * @param boolean $featured 
     * @return Products 
     */ 
     public function setFeatured($featured) { 
      $this->featured = $featured; 

      return $this; 
     } 

     /** 
     * Get featured 
     * 
     * @return boolean 
     */ 
     public function getFeatured() { 
      return $this->featured; 
     } 

     /** 
     * Set enabled 
     * 
     * @param boolean $enabled 
     * @return Products 
     */ 
     public function setEnabled($enabled) { 
      $this->enabled = $enabled; 

      return $this; 
     } 

     /** 
     * Get enabled 
     * 
     * @return boolean 
     */ 
     public function getEnabled() { 
      return $this->enabled; 
     } 

     /** 
     * Set free_shipping 
     * 
     * @param boolean $freeShipping 
     * @return Products 
     */ 
     public function setFreeShipping($freeShipping) { 
      $this->free_shipping = $freeShipping; 

      return $this; 
     } 

     /** 
     * Get free_shipping 
     * 
     * @return boolean 
     */ 
     public function getFreeShipping() { 
      return $this->free_shipping; 
     } 

     /** 
     * Set price 
     * 
     * @param string $price 
     * @return Products 
     */ 
     public function setPrice($price) { 
      $this->price = $price; 

      return $this; 
     } 

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

     /** 
     * Set sku 
     * 
     * @param integer $sku 
     * @return Products 
     */ 
     public function setSku($sku) { 
      $this->sku = $sku; 

      return $this; 
     } 

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

     /** 
     * Set arrival_date 
     * 
     * @param \DateTime $arrivalDate 
     * @return Products 
     */ 
     public function setArrivalDate($arrivalDate) { 
      $this->arrival_date = $arrivalDate; 

      return $this; 
     } 

     /** 
     * Get arrival_date 
     * 
     * @return \DateTime 
     */ 
     public function getArrivalDate() { 
      return $this->arrival_date; 
     } 

     /** 
     * Set update_date 
     * 
     * @param \DateTime $updateDate 
     * @return Products 
     */ 
     public function setUpdateDate($updateDate) { 
      $this->update_date = $updateDate; 

      return $this; 
     } 

     /** 
     * Get update_date 
     * 
     * @return \DateTime 
     */ 
     public function getUpdateDate() { 
      return $this->update_date; 
     } 

     /** 
     * Set category_id 
     * 
     * @param \SCWDesignsBundle\Entity\Products\ProductCategories $categoryId 
     * @return Products 
     */ 
     public function setCategoryId(\SCWDesignsBundle\Entity\Products\ProductCategories $categoryId = null) { 
      $this->category_id = $categoryId; 

      return $this; 
     } 

     /** 
     * Get category_id 
     * 
     * @return \SCWDesignsBundle\Entity\Products\ProductCategories 
     */ 
     public function getCategoryId() { 
      return $this->category_id; 
     } 

     /** 
     * Set participate_sale 
     * 
     * @param \SCWDesignsBundle\Entity\Products\ProductSales $participateSale 
     * @return Products 
     */ 
     public function setParticipateSale(\SCWDesignsBundle\Entity\Products\ProductSales $participateSale = null) { 
      $this->participate_sale = $participateSale; 

      return $this; 
     } 

     /** 
     * Get participate_sale 
     * 
     * @return \SCWDesignsBundle\Entity\Products\ProductSales 
     */ 
     public function getParticipateSale() { 
      return $this->participate_sale; 
     } 

     /** 
     * Set description 
     * 
     * @param \SCWDesignsBundle\Entity\Products\ProductDescrition $description 
     * @return Products 
     */ 
     public function setDescription($description) { 
      $this->description = $description; 

      return $this; 
     } 

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

實體 - ProductDescription.php

<?php 
    namespace SCWDesignsBundle\Entity\Products; 

    use Doctrine\ORM\Mapping as ORM; 
    use SCWDesignsBundle\Entity\BaseEntity; 
    use Symfony\Component\Validator\Mapping\ClassMetaData; 
    use Symfony\Component\Validator\Constraints as Assert; 

    /** 
    * @ORM\Entity 
    * @ORM\Table(name="product_description") 
    */ 
    class ProductDescription extends BaseEntity { 
     /** 
     * @ORM\ManyToOne(targetEntity="Products") 
     * @ORM\JoinColumn(name="product_id", referencedColumnName="id", onDelete="CASCADE") 
     */ 
     protected $product_id; 

     /** 
     * @ORM\Column(type="string", columnDefinition="VARCHAR(255)") 
     * @Assert\Length(
     *  min = 2, 
     *  max = 255, 
     *  minMessage = "The item name must be at least {{ limit }} characters long.", 
     *  maxMessage = "The item name cannot be longer than {{ limit }} characters." 
     *) 
     * @Assert\NotBlank() 
     */ 
     protected $name; 

     /** 
     * @ORM\Column(type="text") 
     * @Assert\NotBlank() 
     */ 
     protected $brief_description; 

     /** 
     * @ORM\Column(type="text") 
     * @Assert\NotBlank() 
     */ 
     protected $full_description; 

     /** 
     * @ORM\Column(type="string", columnDefinition="VARCHAR(255)") 
     * @Assert\Length(
     *  min = 2, 
     *  max = 255, 
     *  minMessage = "The tags characters must be at least {{ limit }} characters long.", 
     *  maxMessage = "The tags characters cannot be longer than {{ limit }} characters." 
     *) 
     * @Assert\NotBlank() 
     */ 
     protected $meta_tags; 

     /** 
     * @ORM\Column(type="string", columnDefinition="VARCHAR(255)") 
     * @Assert\Length(
     *  min = 2, 
     *  max = 255, 
     *  minMessage = "The tags title must be at least {{ limit }} characters long.", 
     *  maxMessage = "The tags title cannot be longer than {{ limit }} characters." 
     *) 
     * @Assert\NotBlank() 
     */ 
     protected $meta_title; 

     /** 
     * @ORM\Column(type="text") 
     * @Assert\NotBlank() 
     */ 
     protected $meta_description; 

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

      return $this; 
     } 

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

     /** 
     * Set brief_description 
     * 
     * @param string $briefDescription 
     * @return ProductDescription 
     */ 
     public function setBriefDescription($briefDescription) { 
      $this->brief_description = $briefDescription; 

      return $this; 
     } 

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

     /** 
     * Set full_description 
     * 
     * @param string $fullDescription 
     * @return ProductDescription 
     */ 
     public function setFullDescription($fullDescription) { 
      $this->full_description = $fullDescription; 

      return $this; 
     } 

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

     /** 
     * Set meta_tags 
     * 
     * @param string $metaTags 
     * @return ProductDescription 
     */ 
     public function setMetaTags($metaTags) { 
      $this->meta_tags = $metaTags; 

      return $this; 
     } 

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

     /** 
     * Set meta_title 
     * 
     * @param string $metaTitle 
     * @return ProductDescription 
     */ 
     public function setMetaTitle($metaTitle) { 
      $this->meta_title = $metaTitle; 

      return $this; 
     } 

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

     /** 
     * Set meta_description 
     * 
     * @param string $metaDescription 
     * @return ProductDescription 
     */ 
     public function setMetaDescription($metaDescription) { 
      $this->meta_description = $metaDescription; 

      return $this; 
     } 

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

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

     /** 
     * Set product_id 
     * 
     * @param \SCWDesignsBundle\Entity\Products\Products $productId 
     * @return ProductDescription 
     */ 
     public function setProductId(\SCWDesignsBundle\Entity\Products\Products $productId = null) { 
      $this->product_id = $productId; 

      return $this; 
     } 

     /** 
     * Get product_id 
     * 
     * @return \SCWDesignsBundle\Entity\Products\Products 
     */ 
     public function getProductId() { 
      return $this->product_id; 
     } 
    } 

FormType - NewProductFormType.php

<?php 
    namespace SCWDesignsBundle\Form\Admin; 

    use Symfony\Component\Form\AbstractType; 
    use Symfony\Component\Form\FormBuilderInterface; 
    use Symfony\Component\OptionsResolver\OptionsResolverInterface; 
    use SCWDesignsBundle\Form\Types\ProductDescriptionType; 

    class NewProductFormType extends AbstractType { 
     private $entityManager; 

     public function __construct($entityManager) { 
      $this->entityManager = $entityManager; 
     } 

     public function buildForm(FormBuilderInterface $builder, array $options) { 
      $builder 
       ->add('featured', 'checkbox', array('label' => 'Featured', 'required' => false)) 
       ->add('enabled', 'checkbox', array('label' => 'Enabled', 'required' => false)) 
       ->add('freeshipping', 'checkbox', array('label' => 'Free Shipping', 'required' => false)) 
       // ->add('participate_sale', 'checkbox', array('label' => 'Sale', 'required' => false)) 
       ->add('price', 'text', array('label' => 'Price', 'required' => true)) 
       ->add('sku', 'text', array('label' => 'Sku', 'required' => false)) 
       ->add('description', 'collection', array(
        'type' => new ProductDescriptionType(), 
        'allow_add' => true, 
        'by_reference' => true 
       )) 
       ->add('category_id', 'entity', array(
        'class' => 'SCWDesignsBundle:Products\ProductCategories', 
        'property' => 'name', 
        'placeholder' => false 
       )); 
     } 

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

類型 - ProductDescriptionType.php

<?php 
    namespace SCWDesignsBundle\Form\Types; 

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

    class ProductDescriptionType extends AbstractType { 
     public function buildForm(FormBuilderInterface $builder, array $options) { 
      $builder 
       ->add('name', null, array('label' => 'Product Name', 'required' => true)) 
       ->add('full_description', 'textarea', array('label' => 'Full Description', 'required' => false)) 
       ->add('brief_description', 'textarea', array('label' => 'Brief Description', 'required' => false)) 
       ->add('meta_tags', null, array('label' => 'Meta Tags', 'required' => false)) 
       ->add('meta_title', null, array('label' => 'Meta Title', 'required' => false)) 
       ->add('meta_description', 'text', array('label' => 'Meta Description', 'required' => false)); 
     } 

     public function setDefaultOptions(OptionsResolverInterface $resolver) { 
      $resolver->setDefaults(array('data_class' => '\SCWDesignsBundle\Entity\Products\ProductDescription')); 
     } 

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

控制器 - ProductsController.php

public function addProductAction(Request $request) { 
      $categories = $this->getCategories(); 
      $em = $this->getDoctrine()->getEntityManager(); 
      $product = new Products(); 
      $form = $this->createForm(new NewProductFormType($em), $product); 
      $form->handleRequest($request); 
      if ($form->isValid()) { 
       $date = new \DateTime('NOW'); 
       $product->setUpdateDate($date); 
       $em->persist($product); 
       $em->flush(); 

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

      return $this->render('SCWDesignsBundle:Admin\Products\Actions:new.html.twig', array(
       'active_page' => 'products', 
       'categories' => $categories, 
       'form' => $form->createView(), 
       'action' => $this->generateUrl('scw_designs_admin_products_new') 
      )); 
     } 
+0

我試過多種變化,這只是我請求幫助之前嘗試的最後一個變體。 –

+0

沒有深入研究你的代碼:你是否確定你的控制器在關係的兩端都設置了Product/ProductDescription? – Chris

+0

此外,您還可以在Products中使用OneToOne,但在ProductDescription中使用ManyToOne。那些不匹配。運行'php app/console doctrine:schema:validate'並解析所有的映射錯誤。 – Chris

回答

0

由於這個緣故,我頗有幾分悲傷的我決定在官方#symfony IRC頻道sshaun和ddproxy工作後張貼我的答案。

首先,我確實有自己的關係錯了。需要將反轉切換到product.php。第二,我需要預先處理數據,所以我將下面的內容添加到控制器中,瞧,好像魔法一樣。

  if ($form->isValid()) { 
       $date = new \DateTime('NOW'); 
       $product->setUpdateDate($date); 
       $em->persist($product); 
       $em->flush(); 
       $description = $product->getDescription()->first(); 
       $description->setProductId($product); 
       $em->persist($description); 
       $em->flush(); 

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