OneToOne Unidirectional Collection不持久化数据

时间:2015-07-10 06:23:14

标签: php symfony doctrine associations entity

我正在尝试在两个实体之间创建OneToOne Undirectional关系。我已经创建了模式,但是当我提交表单时,它不会将数据持久化到集合中。基于我的所有研究,我怀疑这是因为我没有正确设置所有实体,但我已经尝试了所有可以解决它而没有运气。

实体 - 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';
        }
    }

Controller - 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')
            ));
        }

1 个答案:

答案 0 :(得分:0)

由于这让我感到非常悲痛,所以我决定在官方#symfony irc频道使用sshaun和ddproxy后发布我的答案。

首先,我确实拥有错误的拥有关系。需要将inversedby切换到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'));
            }