Предотвратить сброс сопоставленных данных

Вопрос или проблема

Я хотел бы узнать, есть ли возможность исключить некоторые поля формы из сохранения/отправки в базу данных (но при этом оставить '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() один раз для всех объектов. Это снизит количество транзакций к базе данных и улучшит производительность.

Заключение

Используя предложенные методы, вы сможете избежать нежелательного фиксирования данных, тем самым сохранив функциональность формы и осуществив полноценное управление данными. Надеюсь, эти рекомендации окажутся полезными для вас, и вы сможете успешно решить свою задачу.

Оцените материал
Добавить комментарий

Капча загружается...