In CakePHP, come puoi determinare se un campo è stato cambiato in un'azione di modifica?

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

  •  02-07-2019
  •  | 
  •  

Domanda

Sto usando il cacheCounter in CakePHP , che incrementa un contatore per i campi correlati.

Esempio, ho una tabella Person una tabella Source. Person.source_id esegue il mapping a una riga nella tabella di origine. Ogni persona ha una Sorgente e ogni Sorgente ha nessuna o più righe Persona.

cacheCounter funziona alla grande quando cambio il valore di una fonte su una persona. Incrementa Source.Person_Count . Cool.

Ma quando aumenta, lo aggiunge alla fonte di destinazione per una persona, ma non lo rimuove dal vecchio valore. Ho provato updateCacheControl () in afterSave , ma non ha fatto nulla.

Quindi ho scritto un codice nel mio modello per afterSave che avrebbe sottratto l'origine source_id, ma lo ha sempre fatto anche quando non stavo nemmeno cambiando source_id . (Quindi il conteggio è diventato negativo).

La mia domanda: esiste un modo per sapere se un campo è stato modificato nel modello in CakePHP ?

È stato utile?

Soluzione

Per monitorare le modifiche in un campo, è possibile utilizzare questa logica nel modello senza apportare modifiche altrove:

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

Altri suggerimenti

Con riferimento a Alexander Morland Rispondi.

Che ne dici di questo invece di scorrere in loop prima del filtro.

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

Riceverai chiave oltre che valore.

Nella vista di modifica, includi un altro campo nascosto per il campo che desideri monitorare ma aggiungi il nome del campo con qualcosa come " _prev " e imposta il valore sul valore corrente del campo che desideri monitorare. Quindi, nell'azione di modifica del controller, fai qualcosa se i due campi non sono uguali. per es.

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

Le modifiche avvengono raramente, quindi un'altra selezione prima di eseguire l'aggiornamento non è un grosso problema, quindi, recupera il record prima di salvare, salvalo, confronta i dati inviati nel modulo di modifica con i dati che hai recuperato dal db prima di te salvato, se è diverso, fare qualcosa.

Verifica se " salva " utilizza una sorta di chiamata DBAL che restituisce "righe interessate", in genere questo è il modo in cui è possibile giudicare se l'ultima query ha modificato i dati o in caso contrario. Perché se così non fosse, le righe interessate dopo un'istruzione UPDATE sono 0.

Puoi chiamare getAffectedRows () su qualsiasi classe di modello.

Dal modello di classe:

/**
 * 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();
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top