Как в CakePHP определить, было ли изменено поле при действии редактирования?
Вопрос
я использую 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();
}