Я спрашиваю себя что-то... Вот вопрос:
У меня есть запрос модели. Эта модель имеет статус. (допустим, это целое число)
Поскольку статус изменится с течением времени, и поскольку я хочу вести запись об изменениях, было ясно, что статус не будет полем таблицы/модели запроса.
Я думал, что добавлю таблицу/модель RequestStatus и скажу CakePHP
Request
hasMany RequestStatus
Тогда я подумал, что будет просто получить весь запрос, который имеет только действительный статус.
Но я был неправ.
Использование сдерживаемого не является хорошим, поскольку оно возвращает запрос, даже если у него неправильный статус (или даже если у него нет статуса).
Итак, я протестировал 2 решения:
Привязка "на лету" модели RequestStatus как отношения hasOne, но она не работает должным образом
При подключении используйте ключ соединения/массив.
Очевидно, что я пропустил, потому что это не работает.
Я что-то упускаю? Или лучший способ сделать это - наличие поля статуса в таблице запроса?
EDIT: Я забыл упомянуть, что мне нужно использовать этот запрос с разбиением на страницы CakePHP
Я возьму пару вещей, которые вы не упомянули. Прежде всего, я полагаю, вы также создали RequestStatus belongsTo Request
. И я полагаю, что ваша таблица RequestStatus имеет четыре столбца: id
, status
, request_id
и created
. Столбец request_id
является внешним ключом и created
волшебное поле, которое CakePHP заполняет при создании новой строки. Я также предполагаю, что вы используете Containable поведение.
При этом вы можете использовать три способа:
1) Вы можете получить последние действительные статусы вместе с их запросами.
В вашей RequestModel:
public function getValidRequests() {
$db = $this->RequestStatus->getDataSource();
$subquery = $db->buildStatement(array(
'fields' => array('request_id', 'max(created) as lastcreated'),
'table' => $db->fullTableName($this->RequestStatus),
'alias' => 'temp',
'group' => array('request_id')
), $this->RequestStatus);
return $this->RequestStatus->find('all', array(
'contain' => array('Request'),
'joins' => array(
array(
'table' => '(' . $subquery . ')',
'alias' => 'rs2',
'type' => 'right',
'conditions' => array(
'RequestStatus.request_id = rs2.request_id',
'RequestStatus.created = rs2.lastcreated'
)
)
),
'conditions' => array('RequestStatus.status' => 1),
'order' => array('RequestStatus.request_id' => 'desc')
));
}
2) Вы можете получить все запросы с их статусом, а затем вернуть только те, у которых есть последний действительный статус.
В вашей RequestModel:
public function getValidRequests() {
$requests = $this->find('all', array(
'contain' => array(
'RequestStatus' => array(
'order' => array('RequestStatus.created' => 'desc')
)
)
));
$result = array();
foreach ($requests as $request) {
if ($request['RequestStatus'][0]['status'] == 1)
$result[] = $request;
}
return $result;
}
3) Денормализация.
Добавьте столбец last_status
в таблицу Request
. Поэтому каждый раз, когда вы обновляете статус запроса, вставьте этот новый статус в таблицу RequestStatus
и сохраните этот новый статус в Request.last_status
. Теперь вы можете просто сделать:
public function getValidRequests() {
return $this->find('all', array(
'conditions' => array('Request.last_status' => 1)
));
}
having
вместоconditions
, так как фильтр сделан после того, как заказ и группа сделаны. Я отредактирую это.