简体   繁体   中英

Symfony2 Form Persistance in an One-to-Many-Many-To-One relation

I have an one-to-many-to-one structure which looks like this: (code below)
Room (id, ..., roomSeatings)
RoomSeating (id, room, seating, capacity )
Seating (id, ..., roomSeatings)
seating means seat placement inside a room, ie: u-shaped

My goal is to generate a form having:
room imformation (done)
seating information for a room (checkboxes with seatings where you select which seatings are available for the room AND below, for each seating, a text field in which you input the maximum capacity for each seating.)
输出样本

I wouldn't like to pre-populate the relation entity with all possible combinations of rooms + seatings because this definitely doesn't scale up very well
(example: for 10000 rooms * 10 available seatings => 100 000 entries, whereas if we only store the association and assume that each room has an average of 5 seatings we get half the number of entries=> 50 000)

Question: Which is the best form type setup which allows me to achieve a clean, hack-free implementation?

I have a working-ish implementation which is definitely not pretty.
The problem lies in creating the form type for the association, because I need to show all the seatings available and check those which are selected(the mapping doesn't do this for me, it only retrieves the selected ones.)

Any ideas?


Code samples:

Room:


/**
 * Room
 *
 * @ORM\Table(name="rooms")
 * @ORM\Entity(repositoryClass="...\RoomRepository")
 */
class Room
{

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

    (...)

    /**
     * @var ArrayCollection $roomSeatings;
     *
     * @ORM\OneToMany(targetEntity="...\RoomSeating", mappedBy="room", cascade={"all"})
     */
    protected $roomSeatings;

Seating:


/**
 * 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:


/**
 * 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;

You are not editing the "Seating" entity, it is only a possible choice in one of the properties for RoomSeating.

The best solution would probably be to have Room be the primary entity you are editing and RoomSeating as an embedded form. See http://symfony.com/doc/master/cookbook/form/form_collections.html The documentation also explains how to add/remove records.

The only thing remaining is how to get this working in your interface on the webpage.

You could adjust it to make an "add seating"-button to "adds a row" where the user also has to select the Seating. This would be the most simple and most standard Symfony2 implementation.

Or you could use checkboxes that are outside your actual form to trigger the creation/removal of "rows" in the embedded form using javascript. This way you could also display nicely which capacity-value belongs to what seating arrangement.

Both options would also you to add additional fields easily to the RoomSeating entity if the may be required in the future.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM