Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedding a collection of forms Symfony2 forms with adding and deleting allowed

In Symfony2, if I embed a collection of forms pointing at a many to one relationship in Doctrine and allow adding and deletion, if I delete a record from the beginning, add one at the end, and edit some in the middle how does the system know which records to update with which data?

There is nothing in the tutorial that passes the primary key of the embedded data around. Under certain circumstances, my records are getting needlessly deleted and added again rather than edited in place (even if there are no changes to the particular record). This breaks the fields on the records that are not included on the form, setting them to their default values from the DB model.

Is there a way to pass the primary key in the form and have it used to perform updates when the data comes back?

like image 298
rjmunro Avatar asked Mar 07 '13 14:03

rjmunro


Video Answer


2 Answers

If you want to index the collection (by the entity id) for all querys, you can simply use the indexBy annotation in your entity class.

/**
 * @ORM\OneToMany(targetEntity="EntityClass", mappedBy="EntityVariable", indexBy="id")
 */
private $collection;
like image 162
Akkumulator Avatar answered Oct 21 '22 12:10

Akkumulator


Based on the Akkumulator's answer and comment and some experimentation, I did this:

Create new fields (using Javascript as described in the documentation) with __name__ replaced not by a number but by a string: new_ followed by an forever increasing number that has nothing to do with the list (e.g. new_1, new_2, new_3...)

I don't have to push the primary keys into the forms and I don't need indexBy either - that's good, because indexBy felt like it was too far removed from the form, ending in having the Action at a distance anti-pattern.

Why this works:

  • PHP arrays aren't like those in other languages. They're always dictionaries, so you can add string keys to them even if they only have numeric keys to start with.
  • Because the Symfony collection is mapped by field name, new fields will not match existing data and deleted fields will not be matched to existing data (and thus be removed from the set)
like image 25
Radu C Avatar answered Oct 21 '22 13:10

Radu C