Вопрос или проблема
Я хотел бы узнать, есть ли возможность исключить некоторые поля формы из сохранения/отправки в базу данных (но при этом оставить 'mapped' => true
).
Я хочу добиться эффекта, чтобы пользователь добавлял одну строку (Устройство
) с его характеристиками, но с несколькими серийными номерами, а после отправки разделял их и сохранял.
Проблема заключается в данных формы, потому что, когда я сопоставил свои данные с формой, вызов $em->flush()
сохранит все сопоставленные данные формы, так что все вставленные серийные номера
будут сохранены как одно устройство. (А в этом конкретном коде ниже все серийные номера будут сохранены как отдельное устройство + N устройство со всеми серийными номерами.)
$data = $deviceAddForm->getData();
foreach ($data['devices'] as $key => $device) {
$device->setAgreement($a);
$snList = array_filter(preg_split('/[\s,~]+/', $device->getSerialNumber()), 'strlen');
if($device->isAccessory() != true){
foreach ($snList as $key => $sn) {
$d = new Device();
$d->setAgreement($a);
$d->setSerialNumber($sn);
$d->setQuantity(1);
$d->setAccessory(false);
$d->setName($device->getName());
$d->setPartNumber($device->getPartnumber());
$d->setModyfications($device->getModyfications());
$d->setWarrantyEnds($device->getWarrantyEnds());
$d->setSla($device->getSla());
$d->setDeviceCategory($device->getDeviceCategory());
$em->persist($d);
}
} else {
$em->persist($device);
}
}
$em->flush()
$em->flush() дополнительно отправляет устройства, которые находятся в массиве $data[‘devices’].
Я хотел бы как-то предотвратить отправку $data[‘devices’], но все же иметь сопоставленное поле devices
в форме.
Идея отправлять каждое $d
существенно замедляет процесс, так как возникает множество запросов к базе данных.
Ответ или решение
Для решения проблемы, связанной с нежелательной фиксацией (flush) данных в базе данных при использовании формы с полем, которое вы хотите оставить замапленным, но не сохранять, можно рассмотреть несколько подходов. Суть вашей задачи состоит в том, чтобы исключить определенные поля из фиксирования без уменьшения функциональности форм. Ниже приведены шаги и рекомендации, которые помогут вам достичь этой цели.
1. Загрузка данных в форму
Сначала убедитесь, что форма загружает данные корректно, а именно that mapped
установлено в истинное значение ('mapped' => true
). Это нужно для правильной работы вашего объекта.
$data = $deviceAddForm->getData();
2. Обработка данных формы
Ваша основная задача — правильно обработать данные формы, чтобы избежать нежелательной фиксации объектов, которые уже присутствуют в базе данных.
foreach ($data['devices'] as $key => $device) {
// Установка согласия для нового устройства
$device->setAgreement($a);
// Разбиваем серию на отдельные номера
$snList = array_filter(preg_split('/[\s,~]+/', $device->getSerialNumber()), 'strlen');
// Перебор списка серийных номеров
foreach ($snList as $key => $sn) {
$d = new Device();
$d->setAgreement($a);
$d->setSerialNumber($sn);
// Заполнение остальных свойств
$d->setQuantity(1);
$d->setAccessory(false);
// Копируем данные из устройства
$d->setName($device->getName());
$d->setPartNumber($device->getPartnumber());
$d->setModyfications($device->getModyfications());
$d->setWarrantyEnds($device->getWarrantyEnds());
$d->setSla($device->getSla());
$d->setDeviceCategory($device->getDeviceCategory());
// Помещаем в EntityManager
$em->persist($d);
}
// Условное сохранение оригинального устройства, если оно аксессуар
if ($device->isAccessory() == true) {
// Возможно, здесь вам придется использовать специальный флаг для отслеживания, стоит ли фиксировать
$em->persist($device);
}
}
3. Избегание лишних данных при фиксировании
Чтобы предотвратить фиксирование ненужных данных из массива $data['devices']
во время выполнения flush()
, вы можете использовать специальное поле или свойство, чтобы отслеживать, стоит ли выполнять фиксирование. Например, добавьте свойство $prePersist
в ваш класс. Затем проверяйте это свойство перед вызовом flush()
.
if (!$prePersist) {
// Не фиксируем устройство, если оно не было изменено
$em->detach($device);
}
4. Оптимизация производительности
Если вы работаете с большим количеством данных и каждое выполнение flush()
вызывает задержки из-за множества запросов в базу данных, рекомендуется использовать следующий подход:
- Используйте пакетное фиксирование. Сначала выполните
persist
для всех записей и затем вызовитеflush()
один раз для всех объектов. Это снизит количество транзакций к базе данных и улучшит производительность.
Заключение
Используя предложенные методы, вы сможете избежать нежелательного фиксирования данных, тем самым сохранив функциональность формы и осуществив полноценное управление данными. Надеюсь, эти рекомендации окажутся полезными для вас, и вы сможете успешно решить свою задачу.