【问题标题】:Symfony 3 multiple entities in one formSymfony 3 多个实体以一种形式出现
【发布时间】:2017-03-27 08:21:00
【问题描述】:

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

一辆公共汽车(或所有公共汽车)有许多便利设施(如空调、WiFi、厨房......),每一种都需要定制价格。假设我们的公共汽车有空调。这辆巴士的空调费用为 50 美元,但其他巴士的空调费用可能为 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';
    }


}

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

    而且您不需要第三个实体(“巴士车辆便利设施”)。

    【讨论】:

      猜你喜欢
      • 2018-03-13
      • 1970-01-01
      • 2014-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-19
      • 1970-01-01
      相关资源
      最近更新 更多