symfony2:一对多关系和嵌入式表单

时间:2014-10-15 18:38:45

标签: symfony symfony-forms

我有以下3个实体。请注意,PedidoOrder / Cart类似,SubitemProduct类似。

Pedido:

namespace Project\FrontendBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
//use Gedmo\Mapping\Annotation as Gedmo;

/**
 * Project\FrontendBundle\Entity\Pedido
 *
 * @ORM\Table
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 */
class Pedido
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="User", inversedBy="pedidos")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false)
     **/
    private $user;

    /**
     * @ORM\OneToMany(targetEntity="PedidoSubitem", mappedBy="pedido", cascade={"persist", "remove"})
     **/
    private $pedidoSubitems;

    /**
     * @ORM\Column(type="float", name="subtotal")
     */
    private $subtotal;

    /**
     * @ORM\Column(type="float", name="iva")
     */
    private $iva;

    /**
     * @ORM\Column(type="float", name="total")
     */
    private $total;

    /**
     * @ORM\Column(type="text", length=5000, name="notas", nullable=true)
     *
     * @var text $notas
     */
    private $notas;

    /**
     * @var \DateTime $created
     *
     * @ORM\Column(type="datetime")
     */
    private $created;

    /**
     * @var \DateTime $updated
     *
     * @ORM\Column(type="datetime", nullable=true)
     */
    private $updated;

    /**
     * @var \DateTime $contentChanged
     *
     * @ORM\Column(name="content_changed", type="datetime", nullable=true)
     */
    private $contentChanged;


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


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

    /**
     * Set cliente
     *
     * @param \Project\FrontendBundle\Entity\Cliente $cliente
     * @return Pedido
     */
    public function setCliente(\Project\FrontendBundle\Entity\Cliente $cliente = null)
    {
        $this->cliente = $cliente;

        return $this;
    }

    /**
     * Get cliente
     *
     * @return \Project\FrontendBundle\Entity\Cliente 
     */
    public function getCliente()
    {
        return $this->cliente;
    }

    /**
     * Add pedidoSubitems
     *
     * @param \Project\FrontendBundle\Entity\PedidoSubitem $pedidoSubitems
     * @return Pedido
     */
    public function addPedidoSubitem(\Project\FrontendBundle\Entity\PedidoSubitem $pedidoSubitems)
    {
        $this->pedidoSubitems[] = $pedidoSubitems;

        return $this;
    }

    public function addPedido(\Project\FrontendBundle\Entity\Pedido $pedido)
    {
      $this->pedidoSubitems[] = $pedido;

    }

    /**
     * Remove pedidoSubitems
     *
     * @param \Project\FrontendBundle\Entity\PedidoSubitem $pedidoSubitems
     */
    public function removePedidoSubitem(\Project\FrontendBundle\Entity\PedidoSubitem $pedidoSubitems)
    {
        $this->pedidoSubitems->removeElement($pedidoSubitems);
    }

    /**
     * Get pedidoSubitems
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getPedidoSubitems()
    {
        return $this->pedidoSubitems;
    }

    /**
     * Set user
     *
     * @param \Project\FrontendBundle\Entity\User $user
     * @return Pedido
     */
    public function setUser(\Project\FrontendBundle\Entity\User $user)
    {
        $this->user = $user;

        return $this;
    }

    /**
     * Get user
     *
     * @return \Project\FrontendBundle\Entity\User 
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * Set notas
     *
     * @param string $notas
     * @return Pedido
     */
    public function setNotas($notas)
    {
        $this->notas = $notas;

        return $this;
    }

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

    /**
     * Set created
     *
     * @param \DateTime $created
     * @return Pedido
     */
    public function setCreated($created)
    {
        $this->created = $created;

        return $this;
    }

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

    /**
     * Set updated
     *
     * @param \DateTime $updated
     * @return Pedido
     */
    public function setUpdated($updated)
    {
        $this->updated = $updated;

        return $this;
    }

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

    /**
     * Set contentChanged
     *
     * @param \DateTime $contentChanged
     * @return Pedido
     */
    public function setContentChanged($contentChanged)
    {
        $this->contentChanged = $contentChanged;

        return $this;
    }

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

    /** 
     *  @ORM\PrePersist 
     */
    public function doStuffOnPrePersist()
    {
        $this->created = new \DateTime("now"); 
    }

    /** 
     *  @ORM\PreUpdate 
     */
    public function doStuffOnPreUpdate()
    {
        $this->updated = new \DateTime("now"); 
    }

    /**
     * Set subtotal
     *
     * @param float $subtotal
     * @return Pedido
     */
    public function setSubtotal($subtotal)
    {
        $this->subtotal = $subtotal;

        return $this;
    }

    /**
     * Get subtotal
     *
     * @return float 
     */
    public function getSubtotal()
    {
        return $this->subtotal;
    }

    /**
     * Set iva
     *
     * @param float $iva
     * @return Pedido
     */
    public function setIva($iva)
    {
        $this->iva = $iva;

        return $this;
    }

    /**
     * Get iva
     *
     * @return float 
     */
    public function getIva()
    {
        return $this->iva;
    }

    /**
     * Set total
     *
     * @param float $total
     * @return Pedido
     */
    public function setTotal($total)
    {
        $this->total = $total;

        return $this;
    }

    /**
     * Get total
     *
     * @return float 
     */
    public function getTotal()
    {
        return $this->total;
    }
}

PedidoSubitem:

namespace Project\FrontendBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * Project\FrontendBundle\Entity\PedidoSubitem
 *
 * @ORM\Table
 * @ORM\Entity(repositoryClass="Gedmo\Sortable\Entity\Repository\SortableRepository")
 */
class PedidoSubitem 
{

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

    /**
     * @ORM\ManyToOne(targetEntity="Pedido", inversedBy="PedidoSubitems", cascade={"persist"})
     * @ORM\JoinColumn(name="pedido_id", referencedColumnName="id")
     **/
    private $pedido;

    /**
     * @ORM\ManyToOne(targetEntity="Subitem", inversedBy="PedidoSubitems", cascade={"persist"})
     * @ORM\JoinColumn(name="subitem_id", referencedColumnName="id")
     **/
    private $subitem;

    /**
     * @ORM\Column(type="integer", name="number", nullable=false)
     *
     * @var integer $number
     */
    protected $number;


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

    /**
     * Set pedido
     *
     * @param \Project\FrontendBundle\Entity\Pedido $pedido
     * @return PedidoSubitem
     */
    public function setPedido(\Project\FrontendBundle\Entity\Pedido $pedido = null)
    {
        $this->pedido = $pedido;

        return $this;
    }

    /**
     * Get pedido
     *
     * @return \Project\FrontendBundle\Entity\Pedido 
     */
    public function getPedido()
    {
        return $this->pedido;
    }

    /**
     * Set subitem
     *
     * @param \Project\FrontendBundle\Entity\Subitem $subitem
     * @return PedidoSubitem
     */
    public function setSubitem(\Project\FrontendBundle\Entity\Subitem $subitem = null)
    {
        $this->subitem = $subitem;

        return $this;
    }

    /**
     * Get subitem
     *
     * @return \Project\FrontendBundle\Entity\Subitem 
     */
    public function getSubitem()
    {
        return $this->subitem;
    }

    /**
     * Set integer
     *
     * @param integer $integer
     * @return PedidoSubitem
     */
    public function setInteger($integer)
    {
        $this->integer = $integer;

        return $this;
    }

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

    /**
     * Set number
     *
     * @param integer $number
     * @return PedidoSubitem
     */
    public function setNumber($number)
    {
        $this->number = $number;

        return $this;
    }

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

子项目:

namespace Project\FrontendBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\Validator\Constraints as Assert;
//use Vich\UploaderBundle\Mapping\Annotation as Vich;
//use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\Common\Collections\ArrayCollection;



/**
 * Project\FrontendBundle\Entity\Subitem
 *
 * @ORM\Table
 * @ORM\Entity
 */
class Subitem
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

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

    /**
     * @ORM\OneToMany(targetEntity="PedidoSubitem", mappedBy="subitem")
     **/
    private $pedidoSubitems;

    /**
     * @var integer $position
     *
     * @ORM\Column(name="position", type="integer")
     */
    private $position;


    /**
     * @ORM\Column(type="string", length=255, name="image_name", nullable=true)
     *
     * @var string $imageName
     */
    protected $imageName;

    /**
     * @ORM\Column(type="boolean", name="activado", nullable=true)
     *
     * @var boolean $activado
     */
    protected $activado = true;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     *
     * @var \DateTime $updatedAt
     */
    protected $updatedAt;

    /**
     * @ORM\Column(type="float", scale=2, name="precio", nullable=true)
     *
     * @var string $precio
     */
    protected $precio;

    /**
     * @ORM\Column(length=128, unique=true)
     */
    private $slug;

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

    public function __toString()
    {
        return $this->nombre;
    }

    public function getSlug()
    {
        return $this->slug;
    }

    /**
     * Set position
     *
     * @param integer $position
     * @return Subitem
     */
    public function setPosition($position)
    {
        $this->position = $position;

        return $this;
    }

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

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

    /**
     * Set tipo
     *
     * @param boolean $tipo
     * @return Product
     */
    public function setTipo($tipo)
    {
        $this->tipo = $tipo;

        return $this;
    }
    /**
     * Set imageName
     *
     * @param string $imageName
     * @return Subitem
     */
    public function setImageName($imageName)
    {
        $this->imageName = $imageName;

        return $this;
    }

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


    public function getImage()
    {
        return $this->image;
    }

    public function setImage($image)
    {
        $this->image = $image;

        if($this->image) {
            $this->updatedAt = new \DateTime('now');
        }
    }

    /**
     * Set updatedAt
     *
     * @param \DateTime $updatedAt
     * @return Product
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

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


    /**
     * Set nombre
     *
     * @param string $nombre
     * @return Subitem
     */
    public function setNombre($nombre)
    {
        $this->nombre = $nombre;

        return $this;
    }

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

    /**
     * Set slug
     *
     * @param string $slug
     * @return Subitem
     */
    public function setSlug($slug)
    {
        $this->slug = $slug;

        return $this;
    }

    /**
     * Set activado
     *
     * @param boolean $activado
     * @return Subitem
     */
    public function setActivado($activado)
    {
        $this->activado = $activado;

        return $this;
    }

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

    /**
     * Set item
     *
     * @param \Project\FrontendBundle\Entity\Item $item
     * @return Subitem
     */
    public function setItem(\Project\FrontendBundle\Entity\Item $item)
    {
        $this->item = $item;

        return $this;
    }

    /**
     * Get item
     *
     * @return \Project\FrontendBundle\Entity\Item
     */
    public function getItem()
    {
        return $this->item;
    }

    /**
     * Add pedidos
     *
     * @param \Project\FrontendBundle\Entity\Pedido $pedidos
     * @return Subitem
     */
    public function addPedido(\Project\FrontendBundle\Entity\Pedido $pedidos)
    {
        $this->pedidos[] = $pedidos;

        return $this;
    }

    /**
     * Remove pedidos
     *
     * @param \Project\FrontendBundle\Entity\Pedido $pedidos
     */
    public function removePedido(\Project\FrontendBundle\Entity\Pedido $pedidos)
    {
        $this->pedidos->removeElement($pedidos);
    }

    /**
     * Get pedidos
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getPedidos()
    {
        return $this->pedidos;
    }

    /**
     * Set precio
     *
     * @param float $precio
     * @return Subitem
     */
    public function setPrecio($precio)
    {
        $this->precio = $precio;

        return $this;
    }

    /**
     * Get precio
     *
     * @return float 
     */
    public function getPrecio()
    {
        return $this->precio;
    }

    /**
     * Add subitems
     *
     * @param \Project\FrontendBundle\Entity\PedidoSubitem $subitems
     * @return Subitem
     */
    public function addSubitem(\Project\FrontendBundle\Entity\PedidoSubitem $subitems)
    {
        $this->subitems[] = $subitems;

        return $this;
    }

    /**
     * Remove subitems
     *
     * @param \Project\FrontendBundle\Entity\PedidoSubitem $subitems
     */
    public function removeSubitem(\Project\FrontendBundle\Entity\PedidoSubitem $subitems)
    {
        $this->subitems->removeElement($subitems);
    }

    /**
     * Get subitems
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getSubitems()
    {
        return $this->subitems;
    }

    /**
     * Add pedidoSubitems
     *
     * @param \Project\FrontendBundle\Entity\PedidoSubitem $pedidoSubitems
     * @return Subitem
     */
    public function addPedidoSubitem(\Project\FrontendBundle\Entity\PedidoSubitem $pedidoSubitems)
    {
        $this->pedidoSubitems[] = $pedidoSubitems;

        return $this;
    }

    /**
     * Remove pedidoSubitems
     *
     * @param \Project\FrontendBundle\Entity\PedidoSubitem $pedidoSubitems
     */
    public function removePedidoSubitem(\Project\FrontendBundle\Entity\PedidoSubitem $pedidoSubitems)
    {
        $this->pedidoSubitems->removeElement($pedidoSubitems);
    }

    /**
     * Get pedidoSubitems
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getPedidoSubitems()
    {
        return $this->pedidoSubitems;
    }
}

这种类型表示:

PedidoType:

namespace Project\FrontendBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Project\FrontendBundle\Form\PedidoSubitemType;

class PedidoType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('user')
            //->add('pedidoSubitem', 'collection', array('type' => new PedidoSubitemType()))
            ->add('pedidoSubitems', new PedidoSubitemType())
            ->add('subtotal')
            ->add('iva')
            ->add('total')
            ->add('notas')
            //->add('created')
            //->add('updated')
            //->add('contentChanged')
        ;
    }

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

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

PedidoSubitemType:

namespace Project\FrontendBundle\Form;

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

class PedidoSubitemType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('number', 'text')
            //->add('pedido')
            ->add('subitem', 'entity', array('class' => 'ProjectFrontendBundle:Subitem'))
        ;
    }

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

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

我想展示一个创建Pedido表单的表单,其中嵌入了PedidoSubitem表单。

正如您在PedidoSubitem中所看到的,我尝试过这两个代码:

案例A

    $builder
        ->add('user')
        ->add('pedidoSubitems', new PedidoSubitemType())

与PedidoSubitemType相关的字段显示正确,但在提交表单后,我得到:

  

属性pedidoSubitems和其中一种方法都没有   addPedidoSubitem(),removePedidoSubitem(),setPedidoSubitems(),   pedidoSubitems(),__ set()或__call()存在且具有公共访问权限   class“Project \ FrontendBundle \ Entity \ Pedido”。 (500内部   服务器错误)

案例B

    $builder
        ->add('user')
        ->add('pedidoSubitem', 'collection', array('type' => new PedidoSubitemType()))

但是在渲染表单({{ form(form) }})时,PedidoSubitemType的字段未显示,只是这样:

<div>
<label class="required">Pedido subitem</label>
<div id="project_frontendbundle_pedido_pedidoSubitem"></div>
</div>

1 个答案:

答案 0 :(得分:0)

您需要使用上面描述的案例A ,但将字段重命名为pedidoSubitem。我的意思是:

$builder->add('pedidoSubitem', new PedidoSubitemType());

可能您应该将实体的方法addPedido()重命名为addPedidoSubitem()