Fat-Free-Framework: Как добавить / изменить / удалить записи связанной таблицы, используя DB\SQL\Mapper

Всем привет, в настоящее время я работаю над формой, которая включает строки из связанной таблицы, и обработка формы представляет собой проблему: в F3, каков наилучший метод для обработки формы, которая может привести к добавлению строк в связанной таблице, изменены или удалены?

Схема БД

practitioner
------------------------------
id         | int(10)
first_name | varchar(255)
last_name  | varchar(255)
abn        | char(11)
mobile     | varchar(20)
email      | varchar(255)

practice_site
------------------------------
id         | int(10)
name       | varchar(255)

provider_number
------------------------------
id               | int(10)
practice_site_id | int(10)
practitioner_id  | int(10)
provider_number  | varchar(20)

Форма

  • Номера провайдеров добавляются динамически, имена форм изменяются с _nнапример, provider_number_3
  • Кнопка удаления удаляет строку в целом, что означает, что может быть provider_number_1 а также provider_number_3 но нет provider_number_2

Форма вывода

Номера провайдеров превращаются в нечто более управляемое, чем *_n,

Другие поля, id, first_nameи т. д. легко обновляются благодаря copyfrom(),

Array
(
    [id] => 1
    [first_name] => Jon
    [last_name] => Doctor
    [abn] => 12345678902
    [mobile] => 0491729472
    [email] => john.doctor@email.com
    [provider_numbers] => Array
        (
            [0] => Array
                (
                    [provider_number] => ASBDF24
                    [practice_site_id] => 2
                )

            [1] => Array
                (
                    [provider_number] => 1249FBK
                    [practice_site_id] => 2
                )

        )

)

Эта проблема

При отправке формы могут возникнуть несколько условий относительно номеров провайдеров:

  • Добавлен новый номер провайдера
  • Номер провайдера изменен
  • Сайт практики изменен
  • Номер провайдера удален

Как лучше всего это сделать? (Предпочтительно с использованием Fat-Free-Framework DB\SQL\Mapper учебный класс).

Возможное решение:

  • Сделать $db->exec() получить массив существующих provider_number стол где provider_id = POST.id
  • Выполнить array_diff() чтобы найти какие-либо записи в базе данных, которые не в форме, а затем сделать DELETE Заявление о тех записях. Усечь исходный массив.
  • Пройдите через массив, глядя ли provider_numberс матча. Если они делают, но practice_site_id отличается, обновите. Если practice_site_id то же самое, ничего не делать.
  • Как точно определить, является ли provider_number изменился для конкретного practice_site_id?

Другая возможность:

  • Измените форму, чтобы включить provider_number.id, когда добавляется новая строка, получить новейший доступный идентификатор из базы данных

1 ответ

Решение

После предложения от @xfra35 в моем вопросе я пошел со второй возможностью - добавление provider_number.id к самой форме и оттуда. Если у вас есть какие-либо дополнительные предложения или советы, пожалуйста, не стесняйтесь поделиться!

Форма была изменена так, что значения были вставлены в provider_numbers[provider_number][] and provider_numbers[practice_site_id][] вместо practice_site_1, practice_site_2, etc, Это сделало код для динамической вставки строк намного проще, так как *_n больше не нужно отслеживать.

<div class="delete-array"> был помещен внутри формы и всякий раз, когда нажимали кнопку удаления, вставлялось следующее: <input type="hidden" name="provider_numbers[delete][]" value="' + id + '" />,

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

var new_id;
$('.btn-add-provider-number').click(function() {

    if (typeof(new_id) === "undefined") {
        $.getJSON({url:'{{ @BASE }}/provider_numbers/new_id.json', async:false}).done(function(data) {
            new_id = data;
        });
    } else {
        new_id++;
    }

    var newRow = ' .... ';
    $('.provider-numbers').append(newRow);
}

Форма отправки теперь выглядит примерно так:

Array
(
    [id] => 1
    [first_name] => Amy
    [last_name] => Doctor
    [abn] => 66627819264
    [mobile] => 0472888798
    [email] => amy.doctor@email.com
    [provider_numbers] => Array
        (
            [delete] => Array
                (
                    [0] => 6
                )

            [provider_number] => Array
                (
                    [0] => 64872HJF
                    [1] => 182947KD
                )

            [practice_site_id] => Array
                (
                    [0] => 1
                    [1] => 2
                )

            [id] => Array
                (
                    [0] => 1
                    [1] => 7
                )
        )
)

Затем обрабатывается следующий код:

$updated = [];
$provider_numbers = [];
$provider_numbers_delete = [];

foreach ($f3->get('POST') as $key => $val) {
    if ($key == 'provider_numbers') {
        foreach ($val as $pn_key => $pn_val) {
            if ($pn_key !== 'delete') {
                foreach ($pn_val as $pnk_key => $pnk_val) {
                    $provider_numbers[$pnk_key][$pn_key] = $pnk_val;
                }
            } else {
                $provider_numbers_delete = $pn_val;
            }
        }
    } else if (is_scalar($val) && $practitioner->exists($key)) {
        $practitioner->set($key, $val);
        $updated[] = $key;
    }
}

if (!empty($provider_numbers)) {
    foreach($provider_numbers as $pn) {
        $provider_number->load(['id = ?', $pn['id']]);
        if ($provider_number->dry()) {
            $provider_number->set('practitioner_id', $f3->get('POST.id'));
        }
        $provider_number->copyfrom($pn);
        $provider_number->save();   
        $updated['provider_numbers'][] = $pn;
    }
}

if (!empty($provider_numbers_delete)) {
    foreach ($provider_numbers_delete as $pnd) {
        $provider_number->load(['id = ?', $pnd]);
        if (!$provider_number->dry()) {
            $provider_number->delete(); 
        }       
    }
}
Другие вопросы по тегам