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

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

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

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'))); 

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

Посмотрите, использует ли «save» какой-то вызов 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(); }