Symfony 3一种形式的多个实体

时间:2017-03-27 08:21:01

标签: php symfony doctrine-orm symfony-forms symfony-3.1

过去两天我坚持这一点。我正在创建巴士旅游网站。目前我正处于向数据库添加新总线的阶段。

一辆公共汽车(或所有公共汽车)都有许多便利设施(如AirCon,WiFi,厨房......),每个都需要定制价格。我们说我们的公共汽车有AirCon。这辆公共汽车的AirCon费用为50美元,但对于其他公共汽车,AirCon可能需要100美元。为此,我创建了3个实体(公交车辆实体,设施实体和公交车辆设施实体)。内部设施实体我将存储公共汽车的Id,舒适性的ID以及该公共汽车ID的便利设施的价格。

问题在于我无法使其发挥作用。在为该字段呈现表单时,我得到了空白的HTML元素。我无法添加或删除多个设施,我不确定它为什么不起作用。

有人知道问题出在哪里吗?

以下是我使用的代码:

设施实体:

<?php

namespace AppBundle\Entity;

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

/**
 * Amenities
 *
 * @ORM\Table(name="amenities", indexes={@ORM\Index(name="administrator_id", columns={"administrator_id"})})
 * @ORM\Entity
 */
class Amenities
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

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

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="created_at", type="datetime", nullable=false)
     */
    private $createdAt = 'CURRENT_TIMESTAMP';

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="modified_at", type="datetime", nullable=false)
     */
    private $modifiedAt = 'CURRENT_TIMESTAMP';

    /**
     * @var \AppBundle\Entity\Users
     *
     * @ORM\ManyToOne(targetEntity="Users")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="administrator_id", referencedColumnName="id")
     * })
     */
    private $administrator;


    /**
     * @ORM\OneToMany(targetEntity="BusVehiclesAmenities", mappedBy="amenities")
     */
    private $amenities;


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

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

        return $this;
    }

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

    /**
     * Set createdAt
     *
     * @param \DateTime $createdAt
     *
     * @return Amenities
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;

        return $this;
    }

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


    /**
     * Constructor
     */
    public function __construct()
    {
        $this->amenities = new ArrayCollection();
    }
    /**
     * Add amenities
     *
     * @param \AppBundle\Entity\BusVehiclesAmenities $amenities
     * @return Amenities
     */
    public function addAmenities(BusVehiclesAmenities $amenities)
    {
        $this->amenities[] = $amenities;

        return $this;
    }

    /**
     * Remove amenities
     *
     * @param \AppBundle\Entity\BusVehiclesAmenities $amenities
     */
    public function removeAmenities(BusVehiclesAmenities $amenities)
    {
        $this->amenities->removeElement($amenities);
    }

    /**
     * Get amenities_bus_vehicles
     *
     * @return ArrayCollection
     */
    public function getAmenities()
    {
        return $this->amenities;
    }

}

巴士车辆实体:

namespace AppBundle\Entity;

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

/**
 * BusVehicles
 *
 * @ORM\Table(name="bus_vehicles", indexes={@ORM\Index(name="company_id", columns={"company_id"}), @ORM\Index(name="bus_type", columns={"bus_type"}), @ORM\Index(name="fuel_type", columns={"fuel_type"}), @ORM\Index(name="emission_class", columns={"emission_class"})})
 * @ORM\Entity
 */
class BusVehicles
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="licence_plate", type="string", length=100, nullable=false)
     */
    private $licencePlate;



    /**
     * @var \AppBundle\Entity\Companies
     *
     * @ORM\ManyToOne(targetEntity="Companies")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="company_id", referencedColumnName="id")
     * })
     */
    private $company;

    /**
     * @var \AppBundle\Entity\BusTypes
     *
     * @ORM\ManyToOne(targetEntity="BusTypes", inversedBy="busType")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="bus_type", referencedColumnName="id")
     * })
     */


    /**
     * @ORM\OneToMany(targetEntity="BusVehiclesAmenities", mappedBy="bus")
     */
    private $busVehiclesAmenities;

    public function __construct()
    {

        $this->busVehiclesAmenities = new ArrayCollection();
    }




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

    /**
     * Add busVehiclesAmenities
     *
     * @param \AppBundle\Entity\BusVehiclesAmenities busVehiclesAmenities
     * @return BusVehicles
     */
    public function addBusVehiclesAmenities(BusVehiclesAmenities $busVehiclesAmenities)
    {
        $this->busVehiclesAmenities[] = $busVehiclesAmenities;

        return $this;
    }

    /**
     * Remove busVehiclesAmenities
     *
     * @param \AppBundle\Entity\BusVehiclesAmenities $busVehiclesAmenities
     */
    public function removeBusVehiclesAmenities(BusVehiclesAmenities $busVehiclesAmenities)
    {
        $this->busVehiclesAmenities->removeElement($busVehiclesAmenities);

    }
    /**
     * Get busVehiclesAmenities
     *
     * @return ArrayCollection
     */
    public function getBusVehiclesAmenities()
    {
        return $this->busVehiclesAmenities;

    }


    /**
     * Set licencePlate
     *
     * @param string $licencePlate
     *
     * @return BusVehicles
     */
    public function setLicencePlate($licencePlate)
    {
        $this->licencePlate = $licencePlate;

        return $this;
    }

    /**
     * Set company
     *
     * @param \AppBundle\Entity\Companies $company
     *
     * @return BusVehicles
     */
    public function setCompany(Companies $company = null)
    {
        $this->company = $company;

        return $this;
    }

    /**
     * Get company
     *
     * @return \AppBundle\Entity\Companies
     */
    public function getCompany()
    {
        return $this->company;
    }



}

巴士设施实体:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * BusVehiclesAmenities
 *
 * @ORM\Table(name="bus_vehicles_amenities", indexes={@ORM\Index(name="amenities_id", columns={"amenities_id"}), @ORM\Index(name="bus_id", columns={"bus_id"})})
 * @ORM\Entity
 */
class BusVehiclesAmenities
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     *
     * @ORM\ManyToOne(targetEntity="BusVehicles", inversedBy="busVehiclesAmenities")
     * @ORM\JoinColumn(name="bus_id", referencedColumnName="id")
     *
     */
    private $bus;

    /**
     *
     * @ORM\ManyToOne(targetEntity="Amenities", inversedBy="amenities")
     * @ORM\JoinColumn(name="amenities_id", referencedColumnName="id")
     *
     */
    private $amenities;

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



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

    /**
     * Set Bus
     *
     * @param \AppBundle\Entity\BusVehicles
     *
     * @return BusVehiclesAmenities
     */
    public function setBus($bus)
    {
        $this->bus = $bus;

        return $this;
    }

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

    /**
     * Set amenities
     *
     * @param \AppBundle\Entity\Amenities
     *
     * @return BusVehiclesAmenities
     */
    public function setAmenities($amenities)
    {
        $this->amenities = $amenities;

        return $this;
    }

    /**
     * Get amenities
     *
     * @return \AppBundle\Entity\Amenities
     */
    public function getAmenities()
    {
        return $this->amenities;
    }
    /**
     * Set price
     *
     * @param float $price
     *
     * @return BusVehiclesAmenities
     */
    public function sePrice($price)
    {
        $this->price = $price;

        return $this;
    }

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

形式:

添加新的总线表单:

<?php

namespace AdminBundle\Form\Type;

use AdminBundle\Form\Type\BusVehiclesAmenitiesType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;




class BusVehiclesType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('licencePlate')
            ->add('company', EntityType::class, array(
                'class' => 'AppBundle:Companies',
                'choice_label' => 'name',

            ->add('busVehiclesAmenities', CollectionType::class, array(
                'entry_type'   => BusVehiclesAmenitiesType::class,
                'allow_add'    => true,
            ));
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\BusVehicles'
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'adminbundle_busvehicles';
    }


}

巴士车辆设施表格

<?php

namespace AdminBundle\Form\Type;

use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\FormBuilderInterface;
use AppBundle\Entity\BusVehiclesAmenities;
use Symfony\Component\OptionsResolver\OptionsResolver;


class BusVehiclesAmenitiesType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('price', MoneyType::class, array(
             'scale' => 2,
            ))
            ->add('amenities', EntityType::class, array(
                'class' =>'AppBundle:Amenities',
                'choice_label' => 'name',
            ))
        ;

    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => BusVehiclesAmenities::class
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'appbundle_busvehiclesamenities';
    }


}

1 个答案:

答案 0 :(得分:2)

我不会将实体类用于表单绑定。 我将创建一个新类(例如BusVehicle),它包含需要在表单上的所有属性(特定字段)并将其用作'data_class'。这样您不仅可以解决问题,还可以将表示层与业务层分离(请参阅Multitier Architecture)。

我通常将这些类放在Form/Model目录中。

在您的情况下,该类将为Form/Model/BusVehicle,并且它将具有$amenities属性。 设施将是一系列Form/Model/Amenity个对象。

您可能需要使用embedded forms,不要将实体类用作'data_object'。成功绑定后,您实例化并填充实体以进行持久化或更新。

并且您不需要第三个实体(“公共汽车设施”)。