处理表单中实体之间关系的正确方法

时间:2013-09-03 12:53:23

标签: symfony doctrine-orm symfony-2.3

我有一个表stock,其关系为1:m,表格为warranty。我为库存表制作了这个实体:

<?php

namespace StockBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints as DoctrineAssert;
use CompanyBundle\Entity\Company;
use StockBundle\Entity\NStockStatus;
use ProductBundle\Entity\NLength;
use ProductBundle\Entity\NWeight;

/**
 * @ORM\Table(name="stock")
 * @ORM\Entity(repositoryClass="StockBundle\Entity\Repository\KStockRepository")
 * @Gedmo\SoftDeleteable(fieldName="deletedAt")
 */
class KStock {

    /**
     * @ORM\Id      
     * @ORM\ManyToOne(targetEntity="ProductBundle\Entity\Product", inversedBy="stocks" )      
     * @ORM\JoinColumn(name="product", referencedColumnName="upc")   
     */
    protected $product;

    /**
     * @ORM\Id      
     * @ORM\ManyToOne(targetEntity="CompanyBundle\Entity\Company", inversedBy="companyHasStock" )      
     * @ORM\JoinColumn(name="company", referencedColumnName="id")   
     */
    protected $company;

    /**
     * 
     * @ORM\ManyToOne(targetEntity="StockBundle\Entity\NCondition", inversedBy="stocks" )      
     * @ORM\JoinColumn(name="kcondition", referencedColumnName="id")   
     */
    protected $condition;

    /**
     * 
     * @ORM\ManyToOne(targetEntity="StockBundle\Entity\NStockStatus", inversedBy="stocks" )      
     * @ORM\JoinColumn(name="status", referencedColumnName="id")   
     */
    protected $status;

    /**
     * 
     * @ORM\ManyToOne(targetEntity="StockBundle\Entity\Warranty", inversedBy="stocks" )      
     * @ORM\JoinColumn(name="warranty", referencedColumnName="id")   
     */
//    protected $warranty;

    /**
     * @ORM\Column(type="string", length=255, name="sku")
     */
    protected $sku;

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

    /**
     * @ORM\Column(type="string", length=255)    
     */
    protected $description;

    /**
     *
     * @ORM\Column(type="decimal", precision=19, scale=4)         
     */
    protected $price;

    /**
     * @ORM\ManyToOne(targetEntity="StockBundle\Entity\NUnit")
     * @ORM\JoinColumn(name="unit", referencedColumnName="id")
     */
    protected $unit;

    /**
     *
     * @ORM\Column(type="decimal", precision=4, scale=2)         
     */
    protected $width;

    /**
     *
     * @ORM\Column(type="decimal", precision=4, scale=2)         
     */
    protected $height;

    /**
     *
     * @ORM\Column(type="decimal", precision=4, scale=2)         
     */
    protected $weight;

    /**
     *
     * @ORM\Column(type="decimal", precision=4, scale=2)         
     */
    protected $length;

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

    /**
     * @ORM\ManyToOne(targetEntity="ProductBundle\Entity\NWeight")
     * @ORM\JoinColumn(name="nweight", referencedColumnName="id")
     */
    protected $nweight;

    /**
     * @ORM\ManyToOne(targetEntity="ProductBundle\Entity\NLength")
     * @ORM\JoinColumn(name="nlength", referencedColumnName="id")
     */
    protected $nlength;

    /**
     * @Gedmo\Timestampable(on="create")
     * @ORM\Column(name="created", type="datetime")
     */
    protected $created;

    /**
     * @Gedmo\Timestampable(on="update")
     * @ORM\Column(name="modified", type="datetime")
     */
    protected $modified;

    /**
     * @ORM\Column(name="deletedAt", type="datetime", nullable=true)
     */
    protected $deletedAt;

    public function setProduct(\ProductBundle\Entity\Product $param) {
        $this->product = $param;
    }

    public function getProduct() {
        return $this->product;
    }

    public function setCompany(\CompanyBundle\Entity\Company $param) {
        $this->company = $param;
    }

    public function getCompany() {
        return $this->company;
    }

    public function setCondition(\StockBundle\Entity\NCondition $condition) {
        $this->condition = $condition;
    }

    public function getCondition() {
        return $this->condition;
    }

    public function setStatus(\StockBundle\Entity\NStockStatus $param) {
        $this->status = $param;
    }

    public function getStatus() {
        return $this->status;
    }

    public function setSku($param) {
        $this->sku = $param;
    }

    public function getSku() {
        return $this->sku;
    }

    public function setAvailability($param) {
        $this->availability = $param;
    }

    public function getAvailability() {
        return $this->availability;
    }

    public function setDescription($description) {
        $this->description = $description;
    }

    public function getDescription() {
        return $this->description;
    }

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

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

    public function setUnit(\StockBundle\Entity\NUnit $unit) {
        $this->unit = $unit;
    }

    public function getUnit() {
        return $this->unit;
    }

    public function setWidth($width) {
        $this->width = $width;
    }

    public function getWidth() {
        return $this->width;
    }

    public function setHeight($height) {
        $this->height = $height;
    }

    public function getHeight() {
        return $this->height;
    }

    public function setWeight($weight) {
        $this->weight = $weight;
    }

    public function getWeight() {
        return $this->weight;
    }

    public function setLength($length) {
        $this->length = $length;
    }

    public function getLength() {
        return $this->length;
    }

    public function setAmount($amount) {
        $this->amount = $amount;
    }

    public function getAmount() {
        return $this->amount;
    }

    public function setCreated($created) {
        $this->created = $created;
    }

    public function getCreated() {
        return $this->created;
    }

    public function setModified($modified) {
        $this->modified = $modified;
    }

    public function getModified() {
        return $this->modified;
    }

    public function getDeletedAt() {
        return $this->deletedAt;
    }

    public function setDeletedAt($deletedAt) {
        $this->deletedAt = $deletedAt;
    }

    public function setNWeight(\ProductBundle\Entity\NWeight $nweight) {
        $this->nweight = $nweight;
    }

    public function getNWeight() {
        return $this->nweight;
    }

    public function setNLength(\ProductBundle\Entity\NLength $nlength) {
        $this->nlength = $nlength;
    }

    public function getNLength() {
        return $this->nlength;
    }

    public function __toString() {
        return $this->company . ' -- ' . $this->product;
    }

}

此实体为保修表:

<?php

namespace StockBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;

/**
 * @ORM\Entity
 * @ORM\Table(name="warranty")
 * @Gedmo\SoftDeleteable(fieldName="deletedAt")
 */
class Warranty {

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     * 
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Warranty")
     * @ORM\JoinColumn(name="parent", referencedColumnName="id")
     */
    protected $parent;

    /**
     * @ORM\ManyToOne(targetEntity="ProductBundle\Entity\Product")
     * @ORM\JoinColumn(name="product", referencedColumnName="upc")
     */
    protected $product;

    /**
     * @ORM\ManyToOne(targetEntity="StockBundle\Entity\NCondition")
     * @ORM\JoinColumn(name="kcondition", referencedColumnName="id")
     */
    protected $kcondition;

    /**
     * @ORM\ManyToOne(targetEntity="CompanyBundle\Entity\Company")
     * @ORM\JoinColumn(name="company", referencedColumnName="id")
     */
    protected $company;

    /**
     *
     * @ORM\Column(type="date")
     */
    protected $valid_time;

    /**
     *
     * @ORM\Column(type="text")
     */
    protected $description;

    /**
     * @Gedmo\Timestampable(on="create")
     * @ORM\Column(name="created", type="datetime")
     */
    protected $created;

    /**
     * @Gedmo\Timestampable(on="update")
     * @ORM\Column(name="modified", type="datetime")
     */
    protected $modified;

    /**
     * @ORM\Column(name="deletedAt", type="datetime", nullable=true)
     */
    protected $deletedAt;

    /**
     * @ORM\OneToMany(targetEntity="StockBundle\Entity\KStock")
     */
    protected $stocks;

    public function getId() {
        return $this->id;
    }

    public function setParent(Warranty $parent = null) {
        $this->parent = $parent;
    }

    public function getParent() {
        return $this->parent;
    }

    public function setDescription($description) {
        $this->description = $description;
    }

    public function getDescription() {
        return $this->description;
    }

    public function setCreated($created) {
        $this->created = $created;
    }

    public function getCreated() {
        return $this->created;
    }

    public function setModified($modified) {
        $this->modified = $modified;
    }

    public function getModified() {
        return $this->modified;
    }

    public function getDeletedAt() {
        return $this->deletedAt;
    }

    public function setDeletedAt($deletedAt) {
        $this->deletedAt = $deletedAt;
    }

    public function setProduct(\ProductBundle\Entity\Product $product) {
        $this->product = $product;
    }

    public function getProduct() {
        return $this->product;
    }

    public function setCompany(\CompanyBundle\Entity\Company $company) {
        $this->company = $company;
    }

    public function getCompany() {
        return $this->company;
    }

    public function setKCondition(\StockBundle\Entity\NCondition $condition) {
        $this->kcondition = $condition;
    }

    public function getKCondition() {
        return $this->kcondition;
    }

    public function setValidTime($valid_time) {
        $this->valid_time = $valid_time;
    }

    public function getValidTime() {
        return $this->valid_time;
    }

}

然后我使用以下代码创建KStockType.php

<?php

namespace StockBundle\Form;

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

class KStockType extends AbstractType {

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options) {

        $builder->add('sku', 'text', array('required' => true, 'label' => 'SKU (Número de Referencia)'))
                ->add('price', 'money', array('label' => 'Precio', 'currency' => 'VEF'))
                ->add('unit', 'entity', array('label' => 'Moneda', 'class' => 'StockBundle:NUnit', 'property' => 'name', 'required' => true, 'multiple' => false, 'expanded' => false))
                ->add('amount', 'integer', array('label' => 'Cantidad'))
                ->add('status', 'entity', array('label' => 'Estado', 'class' => 'StockBundle:NStockStatus', 'property' => 'name', 'required' => true, 'multiple' => false, 'expanded' => false))
                ->add('condition', 'entity', array('label' => 'Condición del producto', 'class' => 'ProductBundle:NCondition', 'property' => 'name', 'required' => true, 'multiple' => false, 'expanded' => false))
                ->add('width', 'integer', array('required' => true, 'label' => 'Ancho'))
                ->add('height', 'integer', array('required' => true, 'label' => 'Alto'))
                ->add('length', 'integer', array('required' => true, 'label' => 'Largo'))
                ->add('nlength', 'entity', array('label' => 'Unidad de Medida', 'class' => 'ProductBundle:NLength', 'property' => 'name', 'required' => true, 'multiple' => false, 'expanded' => false))
                ->add('weight', 'integer', array('required' => true, 'label' => 'Peso'))
                ->add('nweight', 'entity', array('label' => 'Unidad de Peso', 'class' => 'ProductBundle:NWeight', 'property' => 'name', 'required' => true, 'multiple' => false, 'expanded' => false))
                ->add('description', 'textarea', array('label' => 'Descripción'))
                ->add('start_date', 'date', array('label' => 'Fecha (Inicio de la Publicación)', 'widget' => 'single_text', 'format' => 'yyyy-MM-dd', 'attr' => array('class' => 'dpicker')))
                ->add('warranty', 'textarea', array('required' => true, 'label' => 'Condiciones de Garantía'))
                ->add('valid_time', 'date', array('label' => 'Tiempo de Validez de la Garantía', 'widget' => 'single_text', 'format' => 'yyyy-MM-dd', 'attr' => array('class' => 'dpicker')));
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        $resolver->setDefaults(array(
            'data_class' => 'StockBundle\Entity\KStock'
        ));
    }

    /**
     * @return string
     */
    public function getName() {
        return 'stockbundle_kstock';
    }

}

您可能会注意到我在该表单上有一些属于warranty的字段。然后在我的控制器中,我有这种编辑操作的方法:

/**
 * Stock
 * 
 * @Route("/edit/{company_id}/{product_id}", name="stock_edit")
 * @Method("GET")
 */
public function editAction($company_id, $product_id) {
    $em = $this->getDoctrine()->getManager();
    $entity = $em->getRepository('StockBundle:KStock')->findOneBy(array('company' => $company_id, 'product' => $product_id));

    $response = array();
    $response["response"] = true;

    if (!$entity) {
        $response['response'] = FALSE;
        $response['message'] = 'Unable to find Stock entity.';
        return new JsonResponse($response);
    }

    $product = $em->getRepository('ProductBundle:Product')->find($product_id);
    $company = $em->getRepository('CompanyBundle:Company')->find($company_id);

    if (!$product || !$company) {
        $response['response'] = FALSE;
        $response['message'] = 'Error not found product or company';
        return new JsonResponse($response);
    }

    $editForm = $this->createForm(new KStockType(), $entity);
    return $this->render("StockBundle:Stock:edit.html.twig", array('entity' => $entity, 'edit_form' => $editForm->createView()));
}

但是当我打电话给它时我得到了这个错误:

  

属性“start_date”也不是其中一种方法   “getStartDate()”,“isStartDate()”,“hasStartDate()”,“_ get()”或   “ _call()”存在并且在课堂上具有公共访问权限   “StockBundle \实体\ KStock”。

我缺少什么?

2 个答案:

答案 0 :(得分:1)

请看这个页面:Symfony documentation

有点简短:

In more complex examples, you can embed entire forms, which is useful when 
creating forms that expose one-to-many relationships  

我认为你有两种可能的方法:
1 - 了解如何使用关系实体制作表格
2 - 创建一个没有类的表单并管理控制器中的所有信息(我不会使用它)

答案 1 :(得分:0)

尝试通过以下方式替换表单中关于start_date的行:

->add('start_date', 'date', array('label' => 'Fecha (Inicio de la Publicación)', 'widget' => 'single_text', 'format' => 'yyyy-MM-dd', 'attr' => array('class' => 'dpicker'), 'mapped' => false))