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

StackOverflow https://stackoverflow.com/questions/115665

  •  02-07-2019
  •  | 
  •  

Вопрос

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

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

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

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

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

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

Это было полезно?

Решение

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

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

Другие советы

В отношении Александр Морланд Отвечать.

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

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

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

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

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

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

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

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

Из модели класса:

/**
 * 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();
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top