Использование временных таблиц в CakePHP

28 Июл
2011

При разработке небольшого CRUD приложения с помощью фреймворка CakePHP (версия 1.3.10) я столкнулся с одной проблемой. Имеются две таблички со следующими столбцами: incidents id content start_date exp_date 1 demo1 2011-12-12 2011-12-17 2 demo2 2011-12-12 2011-12-13 3 demo3 2011-12-12 2011-12-16 details id incident_id comment comment_id comment_date 1 1 Hi 1 2011-12-12 2 1 Hello 2 2011-12-13 3 1 Bye 3 2011-12-16 4 2 First 1 2011-12-13 5 2 Second 2 2011-12-14 6 3 Third 1 2011-12-17 Мне необходимо было найти те incidents, у которых дата соответствующего максимального comment_id была бы меньше exp_date. В mysql это можно сделать, используя временную таблицу и JOIN’ы. Итоговый запрос выглядит примерно так: CREATE TEMPORARY TABLE temp_details( id int(11) NOT NULL AUTO_INCREMENT, comment_id int(1) NOT NULL, incident_id int(11) NOT NULL, PRIMARY KEY(id)); INSERT INTO temp_details (comment_id, incident_id) SELECT MAX(Detail.comment_id), Detail.incident_id FROM details Detail GROUP BY Detail.incident_id; SELECT Incident.id, Incident.exp_date, Detail.comment_date FROM temp_details TempDetail INNER JOIN details Detail ON TempDetail.incident_id = Detail.incident_id AND TempDetail.comment_id = Detail.comment_id INNER JOIN incidents Incident ON Incident.id = TempDetail.incident_id AND Incident.exp_date > Detail.comment_date; Однако в поваренной книге нет рецепта использования временных таблиц. Поэтому я решил создать модель для неё, чтобы обращаться к данным в рамках ORM фреймворка. Код модели очень прост: class TempDetail extends AppModel { var $name = 'TempDetail'; var $useTable = false; } В итоге в контроллере получилось следующее: $this->Incident->query('CREATE TEMPORARY TABLE temp_details (id int(11) NOT NULL AUTO_INCREMENT, comment_id int(1) NOT NULL, incident_id int(11) NOT NULL, PRIMARY KEY(id));'); $this->Incident->query('INSERT INTO temp_details (comment_id, incident_id) SELECT MAX(Detail.comment_id), Detail.incident_id FROM details Detail GROUP BY Detail.incident_id;'); App::import('Model', 'TempDetail'); //Подлючаем модель TempDetail $this->loadModel('TempDetail'); //Загружаем её в контроллер Перепишем исходный sql запрос: $joins = array( array('table' => 'details', 'alias' => 'Detail', 'type' => 'INNER', 'conditions' => array('Detail.incident_id = TempDetail.incident_id', 'Detail.comment_id = TempDetail.comment_id') ), array('table' => 'incidents', 'alias' => 'Incident', 'type' => 'INNER', 'conditions' => array('TempDetail.incident_id = Incident.id', 'Incident.exp_date > Detail.comment_date) ) ); $this->paginate['TempDetail'] = array('limit' => '25', 'order' => array('Incident.id' => 'desc'), 'joins' => $joins, 'fields' => array('Incident.id', 'Incident.exp_date', 'Incident.start_date')); //аргументы paginate() идентичны find() $incidents = $this->paginate('TempDetail'); //выведем наши данные постранично $this->set('incidents', $incidents);
По материалам Хабрахабр.



загрузка...

Комментарии:

Наверх