В CakePHP, как вы можете определить, было ли поле изменено в действии редактирования? - PullRequest
11 голосов
/ 22 сентября 2008

Я использую cacheCounter в CakePHP, который увеличивает счетчик для связанных полей.

Например, у меня есть таблица Person в таблице Source. Person.source_id отображается на строку в таблице источников. У каждого человека есть один источник, а у каждого источника нет ни одного, ни нескольких строк о человеке.

cacheCounter отлично работает, когда я изменяю ценность источника для человека. Увеличивается Source.Person_Count. Круто.

Но когда он увеличивается, он добавляет его в источник назначения для человека, но не удаляет его из старого значения. Я попытался updateCacheControl() в afterSave, но это ничего не дало.

Итак, я написал в моей модели некоторый код для afterSave, который бы вычитал source_id источника, но он всегда делал это, даже когда я даже не изменял source_id. (Так что счетчик стал отрицательным).

Мой вопрос: есть ли способ узнать, было ли изменено поле в модели в CakePHP?

Ответы [ 6 ]

17 голосов
/ 26 сентября 2008

Чтобы отслеживать изменения в поле, вы можете использовать эту логику в своей модели, без изменений в других местах:

function beforeSave() {
    $this->recursive = -1;
    $this->old = $this->find(array($this->primaryKey => $this->id));
    if ($this->old){
        $changed_fields = array();
        foreach ($this->data[$this->alias] as $key =>$value) {
            if ($this->old[$this->alias][$key] != $value) {
                $changed_fields[] = $key;
            }
        }
    }
    // $changed_fields is an array of fields that changed
    return true;
}
7 голосов
/ 24 августа 2012

Со ссылкой на Александр Морланд Ответ.

Как насчет этого, вместо того, чтобы проходить через него перед фильтром.

$result = array_diff_assoc($this->old[$this->alias],$this->data[$this->alias]);

Вы получите ключ и значение.

1 голос
/ 24 сентября 2008

В представлении редактирования включите другое скрытое поле для поля, которое вы хотите отслеживать, но добавьте к имени поля нечто вроде «_prev» и установите текущее значение поля, которое вы хотите отслеживать. Затем в действии редактирования вашего контроллера сделайте что-нибудь, если два поля не равны. например,

echo $form->input('field_to_monitor');
echo $form->hidden('field_to_monitor_prev', array('value'=>$form->value('field_to_monitor')));
0 голосов
/ 14 сентября 2011

Вы можете вызвать getActedRows () для любого класса модели.

Из класса Модель:

/**
 * Returns the number of rows affected by the last query
 *
 * @return int Number of rows
 * @access public
 */
    function getAffectedRows() {
        $db =& ConnectionManager::getDataSource($this->useDbConfig);
        return $db->lastAffected();
    }
0 голосов
/ 23 сентября 2008

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

0 голосов
/ 23 сентября 2008

Посмотрите, использует ли «save» какой-то вызов DBAL, который возвращает «затронутые строки», обычно именно так вы можете судить, изменил ли последний запрос данные или нет. Потому что, если это не так, затронутые строки после оператора UPDATE равны 0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...