Модель Cakephp с несколькими статусами

0

Я спрашиваю себя что-то... Вот вопрос:

У меня есть запрос модели. Эта модель имеет статус. (допустим, это целое число)

Поскольку статус изменится с течением времени, и поскольку я хочу вести запись об изменениях, было ясно, что статус не будет полем таблицы/модели запроса.

Я думал, что добавлю таблицу/модель RequestStatus и скажу CakePHP

Request hasMany RequestStatus

Тогда я подумал, что будет просто получить весь запрос, который имеет только действительный статус.

Но я был неправ.

Использование сдерживаемого не является хорошим, поскольку оно возвращает запрос, даже если у него неправильный статус (или даже если у него нет статуса).

Итак, я протестировал 2 решения:

  • Привязка "на лету" модели RequestStatus как отношения hasOne, но она не работает должным образом

  • При подключении используйте ключ соединения/массив.

Очевидно, что я пропустил, потому что это не работает.

Я что-то упускаю? Или лучший способ сделать это - наличие поля статуса в таблице запроса?

EDIT: Я забыл упомянуть, что мне нужно использовать этот запрос с разбиением на страницы CakePHP

Теги:
has-many
cakephp
cakephp-2.0

1 ответ

0

Я возьму пару вещей, которые вы не упомянули. Прежде всего, я полагаю, вы также создали 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)
    ));
}
  • 0
    Вы были абсолютно правы в том, что вы предполагаете.
  • 0
    @ azerto00 Перечитав мой ответ, я обнаружил, что метод № 1 не вернет то, что вам нужно. Может быть , лучше использовать having вместо conditions , так как фильтр сделан после того, как заказ и группа сделаны. Я отредактирую это.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню