Подтвердить что ты не робот

В CakePHP, как вы можете определить, было ли поле изменено в действии редактирования?

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

Пример: у меня есть таблица Person a Source table. Person.source_id отображает строку в таблице Source. У каждого человека есть один Источник, и каждый Источник не имеет ни одного или нескольких строк Лица.

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

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

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

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

4b9b3361

Ответ 1

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

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;
}

Ответ 2

Что касается ответа Alexander Morland.

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

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

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

Ответ 3

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

echo $form->input('field_to_monitor');
echo $form->hidden('field_to_monitor_prev', array('value'=>$form->value('field_to_monitor')));

Ответ 4

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

Ответ 5

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

Ответ 6

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

Из класса Model:

/**
 * 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();
    }