У меня есть таблица под названием "Заказы". Эта таблица содержит данные, представляющие бронирование, сделанное для конкретной услуги, со многими переменными.
Некоторое время назад я столкнулся с проблемой с моей текущей структурой данных, в которой любые изменения в бронировании, которые повлияли на время, даты или цены, повлияли бы на другие связанные финансовые записи, списки заказов на даты и т.д.
Мое решение в то время состояло в том, чтобы создать таблицу модификаций, которая будет отслеживать любые изменения, внесенные в бронирование. Затем, всякий раз, когда к модели бронирования было предложено вернуть заказ, оно добавило бы внесенные изменения (в обратном вызове afterFind()
Cake) и представит самую последнюю версию бронирования, что-то вроде этого (извините рисунок рисования ):
Этот метод отлично работает, когда вы попросите модель бронирования вернуть заявку № 1234. Он возвращает самое современное представление бронирования, включая все модификации (накладываемые друг на друга), включая массив, содержащий все модификации и исходные данные бронирования для справки.
Моя проблема заключается в том, что я недавно понял, что мне нужно иметь возможность запрашивать эту модель с пользовательскими условиями, и если одно из этих условий было реализовано в одной из модификаций, результат wouldn 't, потому что модель ищет исходную запись, а не окончательно представленную запись. Пример, когда я запрашиваю модель для возврата строк, где abc
- синий (не серый):
В этом примере модель смотрит прямо на исходные данные для строк, где abc
является синим и не возвращает этот результат, потому что синее значение находится в модификации, которая прикреплена после исходные результаты найдены.
Теперь я сделал запрос в обратном вызове beforeFind()
модели бронирования, чтобы просмотреть изменения, соответствующие заданным критериям, присоединившись к бронированию, чтобы убедиться, что все остальные критерии по-прежнему совпадают. Когда он возвращает синий в примере выше, он сохраняет результат в массиве как свойство класса и продолжается с регулярным find()
, но исключает, что идентификатор бронирования возвращается (потому что мы нашли более современная версия). Затем он объединит их вместе, отсортирует их снова и т.д. В 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 an example
'alias' => 'Booking',
'type' => 'LEFT',
'conditions' => 'Booking.booking_id = Transaction.booking_id'
)
),
'conditions' => array(
'Booking.abc' => 'blue'
)
));
Как вы можете видеть, приведенный выше запрос не будет включать модификацию в моем примере MSPaint выше, поскольку он вручную присоединяется к таблице в SQL (интеграция модификации находится в функциях обратного вызова before
и afterFind()
модель).
Любая помощь по этому поводу будет принята с благодарностью.
Изменить
Я знаю, что это уже достаточно давно, но я подумал, что добавлю, что причина, по которой я хочу отслеживать эти изменения и не обновлять исходную запись, заключается в том, что аспект финансовый не может измениться, потому что это повлияет на отчетность.
Самое быстрое и простое решение, которое я вижу до сих пор, заключается в том, чтобы применять модификации непосредственно к первоначальному бронированию во всех случаях, за исключением случаев, когда это влияет на финансовую информацию, которая по-прежнему отслеживается как модификация (потому что мне в настоящее время не требуется поиск на основе по этой информации).