Эффективное управление изменениями данных

У меня есть стол под названием «Бронирование». Эта таблица содержит данные, представляющие бронирование, сделанное для определенной услуги, со многими переменными.

Некоторое время назад я столкнулся с проблемой с моей текущей структурой данных, из-за которой любые изменения в бронировании, которые влияли на время, даты или цены, влияли бы на другие связанные финансовые записи, списки бронирований на даты и т. Д.

В то время я решил создать таблицу изменений, которая бы отслеживала любые изменения, сделанные в бронировании. Затем, всякий раз, когда модель бронирования просили вернуть бронирование, она добавляла сделанные изменения (в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() функции обратного вызова модели бронирования).

Любая помощь по этому вопросу будет принята с благодарностью.

редактировать

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

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