Эффективное управление изменениями данных
У меня есть стол под названием «Бронирование». Эта таблица содержит данные, представляющие бронирование, сделанное для определенной услуги, со многими переменными.
Некоторое время назад я столкнулся с проблемой с моей текущей структурой данных, из-за которой любые изменения в бронировании, которые влияли на время, даты или цены, влияли бы на другие связанные финансовые записи, списки бронирований на даты и т. Д.
В то время я решил создать таблицу изменений, которая бы отслеживала любые изменения, сделанные в бронировании. Затем, всякий раз, когда модель бронирования просили вернуть бронирование, она добавляла сделанные изменения (вafterFind()
Cake callback) и представьте самую актуальную версию бронирования, что-то вроде этого (извините чертеж Paint):
Этот метод отлично работает, когда вы просите модель бронирования вернуть бронь # 1234. Он возвращает наиболее актуальное представление бронирования, включая все модификации (наслоенные друг на друга), включая массив, содержащий все модификацииа также исходные данные бронирования для справки.
Моя проблема я недавно понял, что мне нужно иметь возможность запрашивать эту модель с пользовательскими условиями, и если одно из этих условий было реализовано в одной из модификаций, результат не будет совпадать, потому что модель скорее ищет исходную запись чем наконец представленный отчет. Пример, где я запрашиваю модель, чтобы вернуть строки, гдеabc
синий (не серый):
В этом примере модель смотрит прямо на исходные данные для строк, гдеabc
синий и не возвращает этот результат, потому что синее значение находится в Модификации, которая прикрепленапосле оригинальные результаты найдены.
Что я сделал сейчас, это поместил запрос вbeforeFind()
Обратный вызов модели бронирования для поиска изменений, соответствующих заданным критериям, присоединение к бронированию, чтобы убедиться, что все остальные критерии все еще соответствуют. Когда он возвращает синий цвет в примере выше, он сохраняет этот результат в массиве как свойство класса и продолжает обычнуюfind()
, ноисключает ID этого бронирования не был возвращен (потому что мы нашли более актуальную версию). Затем он объединит их, снова рассортирует и т. Д. ВafterFind()
.
Это работает, хотя это немного более многословно, на что я надеялся.
После всего этого я понял, что в других частях этого приложения есть модели, которые вручную присоединяются к таблице заказов и выполняют поиск заказов. Так что теперь мне нужен способ, позволяющий включать изменения во все эти ручные объединения прямо в таблицу в MySQL, не затрагивая исходные данные и, желательно, не меняя слишком много кода.
Я думал, что мне нужно удалить ручное соединение и создать вместо него ассоциацию моделей. Будет лиbeforeFind()
а такжеafterFind()
модели бронирования по-прежнему запускаются, когда я запрашиваю, скажем, модель клиента, у которой есть много бронирований (чтобы применить изменения к каждому бронированию)?
Другой вариант - возвращать из MySQL больше строк, чем необходимо, удаляя любые критерии, которые могут содержаться в модификациях, а затем использовать PHP для фильтрации результатов в соответствии с моими критериями поиска. Этот вариант меня немного напугал, потому что результирующий набор может быть массивным без этих критериев ...
Как я могу достичь этой структуры данных? Мои ключевые требования по-прежнему состоят в том, что я не хочу изменять исходную запись о бронировании, а добавить записи об изменениях сверху, но мне нужно иметь возможность запрашивать бронирования (включая модификации) через модель.
Я хочу постараться сохранить как можно большую часть этой интеграции за кулисами, чтобы мне не пришлось просматривать все приложение, чтобы изменитьn
количество запросов, которые выглядят так:
$get_blue = $this->Booking->find('all', array(
'conditions' => array(
'Booking.abc' => 'blue'
)
));
Я хочу иметь возможность неявно включать любые изменения, сделанные в бронировании, чтобы в указанном выше запросе было возвращено актуальное бронирование.
Другая проблема заключается в том, что модель бронирования вручную присоединяется к поисковому запросу, например так:
$get_transactions_on_blue_bookings = $this->Transaction->find('all', array(
'joins' => array(
array(
'table' => 'sql_bookings_table', // non-standard Cake format, I know - it's an example
'alias' => 'Booking',
'type' => 'LEFT',
'conditions' => 'Booking.booking_id = Transaction.booking_id'
)
),
'conditions' => array(
'Booking.abc' => 'blue'
)
));
Как вы можете видеть, приведенный выше запрос не будет включать модификацию в моем примере MSPaint выше, потому что он вручную соединяет таблицу в SQL (интеграция модификации находится вbefore
а такжеafterFind()
функции обратного вызова модели бронирования).
Любая помощь по этому вопросу будет принята с благодарностью.
редактироватьЯ знаю, что это уже достаточно долго, но я решил добавить, что причина, по которой я хочу отслеживать эти изменения, а не обновлять исходную запись, заключается в том, чтофинансовый аспект не может измениться, потому что это повлияет на отчетность.
Самое быстрое и простое решение, которое я пока вижу, это применить изменения непосредственно к исходному бронированию во всех случаях, кроме случаев, когда это влияет на финансовую информацию, которая все еще отслеживается как модификация (потому что в настоящее время мне не нужно искать на основе этой информации ).