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;