Description
The Problem
The main use case of CollectionType is an entity with an associated child entity (with features like allow_add
and allow_delete
). I'm talking about a different situation:
If you have just one entity, you can use a CollectionType to edit (say) 100 existing rows at once, and persist them with just one single form submission.
So far, so good.
But what if the underlying database table changes while you have the form on your screen? This will end up in the submitted field values being persisted to the wrong entities, thereby effectively destroying your table!
Why is that?
- When you create the form in the controller, you pass the result of a query for the collection entries:
Those child entries are then indexed with 0,1,2,... in HTML:
$form = $this->createForm(UsersType::class, ['users' => $userRepository->findSomeUsers()]);
<input name="form[users][0][username]"
- When you submit the form, the same query
$userRepository->findSomeUsers()
is executed again. And ifusers[0]
is not the same row as before, its values are being overwritten.
Suggested Solution
Add an option like 'index_by' => 'id'
to CollectionType which results in using the row's ID for the index in HTML:
<input name="form[users][25687][username]"
If I understand it right, this solution has been suggested before at #7828 but for solving a different problem. I'm opening this new ticket here to illustrate another use case that would also benefit from that feature.