Php Symfony2在一对多多对一关系中形成持续性

Php Symfony2在一对多多对一关系中形成持续性,php,forms,symfony,doctrine-orm,many-to-many,Php,Forms,Symfony,Doctrine Orm,Many To Many,我有一个一对多对一的结构,如下所示:(下面的代码) 房间(id,…,房间座位) 房间座位(id、房间、座位,容量) 座位(id,…,房间座位) 座位是指房间内的座位位置,即:u形 我的目标是生成一个具有以下内容的表单: 房间信息(完成) 房间的座位信息(带有座位的复选框,用于选择房间的可用座位,并在每个座位下方的文本字段中输入每个座位的最大容量。) 我不想用所有可能的房间+座位组合预先填充关系实体,因为这显然不能很好地扩展 (例如:对于10000个房间*10个可用座位=>100000个条目,而

我有一个一对多对一的结构,如下所示:(下面的代码)
房间(id,…,房间座位)
房间座位(id、房间、座位,容量
座位(id,…,房间座位)
座位是指房间内的座位位置,即:u形

我的目标是生成一个具有以下内容的表单:
房间信息(完成)
房间的座位信息(带有座位的复选框,用于选择房间的可用座位,并在每个座位下方的文本字段中输入每个座位的最大容量。)

我不想用所有可能的房间+座位组合预先填充关系实体,因为这显然不能很好地扩展
(例如:对于10000个房间*10个可用座位=>100000个条目,而如果我们只存储关联,并假设每个房间平均有5个座位,则会得到一半的条目=>50000)

问题: 哪一种是最好的表单类型设置,可以让我实现干净、无黑客攻击的实现

我有一个正在工作的ish实现,它肯定不漂亮。
问题在于为关联创建表单类型,因为我需要显示所有可用的座位,并检查已选择的座位(映射不会为我这样做,它只检索已选择的座位)

有什么想法吗


代码示例:

房间:

座位:


/**
 * Seating
 *
 * @ORM\Table(name="seatings")
 * @ORM\Entity(repositoryClass="...\SeatingRepository")
 */
class Seating
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var ArrayCollection $roomSeatings;
     *
     * @ORM\OneToMany(targetEntity="...\RoomSeating", mappedBy="seating")
     */
    protected $roomSeatings;
房间座位:


/**
 * RoomSeating
 *
 * @ORM\Table(name="room_seatings", indexes={@ORM\Index(name="room_capacity_idx", columns={"room_id", "capacity"})})
 * @ORM\Entity(repositoryClass="...\RoomSeatingRepository")
 */
class RoomSeating
{

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

    /**
     * @var integer
     *
     * @ORM\Column(name="capacity", type="smallint", options={"unsigned":true})
     */
    protected $capacity;

    /**
     * @ORM\ManyToOne(targetEntity="...\Room", inversedBy="roomSeatings")
     * @ORM\JoinColumn(name="room_id", referencedColumnName="id", nullable=false)
     */
    protected $room;

    /**
     * @ORM\ManyToOne(targetEntity="...\Seating", inversedBy="roomSeatings")
     * @ORM\JoinColumn(name="seating_id", referencedColumnName="id", nullable=false)
     */
    protected $seating;
您没有编辑“座位”实体,它只是RoomSeating属性之一中的一个可能选项

最好的解决方案可能是将Room作为您正在编辑的主要实体,并将RoomSeating作为嵌入式表单。 看见 文档还解释了如何添加/删除记录

剩下的唯一一件事就是如何在你的网页界面上工作

您可以将其调整为“添加座位”-按钮“添加一行”,用户还必须选择座位。这将是最简单、最标准的Symfony2实现

或者,您可以使用实际表单之外的复选框来触发使用javascript创建/删除嵌入表单中的“行”。 这样,您还可以很好地显示哪个容量值属于哪个座位安排


如果将来可能需要,这两个选项还可以帮助您轻松地向RoomSeating实体添加其他字段。

谢谢,您的解决方案确实有效,但它不会产生预期的行为。这意味着像“集合”一样填充“座位和容量”是可行的,但是这两个字段应该像复选框一样起作用。这就是我当前的解决方案的工作原理,但我怀疑这是实现我的目标的最干净的方法。在创建表单之前,您不需要填充所有可能的组合。请看,它确实需要javascript动态添加行(并将隐藏的座位字段设置为正确的值)。您正在处理数据库中的集合。以不同的方式执行可能需要在控制器中使用更多(自定义)代码。事实上,您是对的。我将试一试,但是我正在考虑创建一个自定义表单类型来处理这种情况。如果我可以将“”属性附加到“实体”或“选择”表单类型,那么一切都是现成的,在这种类型中,我将定义实际的选择并定义这些类型的映射方法(即,不仅是外键字段,而且是带有方法的联接表)

/**
 * RoomSeating
 *
 * @ORM\Table(name="room_seatings", indexes={@ORM\Index(name="room_capacity_idx", columns={"room_id", "capacity"})})
 * @ORM\Entity(repositoryClass="...\RoomSeatingRepository")
 */
class RoomSeating
{

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

    /**
     * @var integer
     *
     * @ORM\Column(name="capacity", type="smallint", options={"unsigned":true})
     */
    protected $capacity;

    /**
     * @ORM\ManyToOne(targetEntity="...\Room", inversedBy="roomSeatings")
     * @ORM\JoinColumn(name="room_id", referencedColumnName="id", nullable=false)
     */
    protected $room;

    /**
     * @ORM\ManyToOne(targetEntity="...\Seating", inversedBy="roomSeatings")
     * @ORM\JoinColumn(name="seating_id", referencedColumnName="id", nullable=false)
     */
    protected $seating;