No CakePHP, como você pode determinar se um campo foi alterado em uma ação de edição?

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

  •  02-07-2019
  •  | 
  •  

Pergunta

Eu estou usando o cacheCounter em CakePHP, que incrementa um contador para campos relacionados.

Exemplo, eu tenho uma tabela Person uma tabela de origem. Person.source_id mapeia para uma linha na tabela de origem. Cada pessoa tem uma fonte, e cada Fonte tem nenhum ou muitas linhas Person.

cacheCounter está funcionando muito bem quando eu alterar o valor de uma fonte em uma pessoa. Ele incrementa Source.Person_Count. Arrefecer.

Mas quando se incrementa, ele adiciona-lo à fonte de destino para uma pessoa, mas não removê-lo do valor antigo. Tentei updateCacheControl() em afterSave, mas isso não fez nada.

Então eu escrevi algum código em meu modelo para afterSave que subtrair a fonte SOURCE_ID, mas ele sempre fez isso, mesmo quando eu não estava mesmo mudando o source_id. (Assim, a contagem foi negativo).

A minha pergunta:? Existe uma maneira de saber se um campo foi alterado no modelo em CakePHP

Foi útil?

Solução

Para monitorar mudanças em um campo, você pode usar esta lógica em seu modelo sem alterações em outros lugares exigidos:

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

Outras dicas

Com referência ao Alexander Morland Resposta.

Como sobre isso em vez de loop através dele antes de filtro.

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

Você vai ter chave, bem como valor também.

No modo de edição, incluir outro campo escondido para o campo que você deseja monitorar, mas sufixo o nome do campo com algo como "_prev" e defina o valor para o valor atual do campo que você deseja monitorar. Então, em ação de edição do seu controlador, fazer algo se os dois campos não são iguais. por exemplo.

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

Edições acontecer com pouca freqüência, então outra escolha antes de fazer a atualização não é grande coisa, então, buscar o registro antes de salvar, salve-o, comparar os dados apresentados no formulário de edição com os dados que você buscados a partir do db antes de salva-lo, se o seu diferente, fazer alguma coisa.

Veja se o "save" usa algum tipo de chamada DBAL que retorna "linhas afetadas", geralmente é assim que você pode julgar se a última consulta os dados alterados, ou se ele não o fez. Porque se não o fez, as linhas afetadas após um UPDATE-declaração são 0.

Você pode chamar getAffectedRows () em qualquer classe de modelo.

De classe 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();
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top