Número de visualizações de um registro no CakePHP
Pessoal, durante esta semana o Dimiguel travou uma batalha feia com o CakePHP para fazer ele contar quantas vezes um determinado registro foi lido. No fim das contas eu achei uma maneira e ele outra... rs... Mas no fim, tudo deu certo...
O problema na verdade estava no Cake insistir em salvar um registro novo, na hora de atualizar o número de views, ao invés de incrementá-lo apenas.
A primeira maneira que encontrei para fazer isso foi a seguinte:
-
function ler($id){
-
$dados = $this->Noticia->findById($id);
-
$this->Noticia->saveField("views", ++$dados['Noticia']['views']);
-
$this->set("data", $dados);
-
}
Para este exemplo, funciona bem porque estamos fazendo a busca pela chave primária da tabela (id), assim depois do findById, $this->Noticia->id não está mais vazio, o que caracteriza qualquer operação de salvamento (neste exemplo $this->saveField) posterior como um update e não a criação de um novo registro na tabela.
O problema é que neste exemplo, se quiséssemos ao invés de buscar pelo id, buscar pela URL, ou outro campo qualquer. Por algum motivo ele não setava $this->Noticia->id com o valor do id, e sendo assim, no salvamento ele criava um outro registro.
A maneira que contornei isso, de uma maneira não muito elegante foi:
-
function ver($idString){
-
$dados = $this->Noticia->findByIdstring($idString);
-
$dados["Noticia"]["views"]++;
-
$this->Noticia->save($dados);
-
$this->set("data", $dados);
-
}
Sendo que aqui $idString foi como chamei a URL que criei para a notícia em questão. E ela não é chave primária. Neste caso se eu tentasse usar o saveField pelo fato de $this->Noticia->id estar vazio ele criaria outro registro. Como mandei salvar o que o findByIdstring retornou, ele atualizou porque $dados["Noticia"]["id"] não estava vazio. Funcionando.:) Mas toda hora mandando todos os campos para o bando, gerando um fluxo de informações um pouco maior.
A outra maneira, que não tinha testado, e o Dimiguel me alertou sobre a possibilidade era:
-
function ler($idString) {
-
$dados = $this->Noticia->findByIdstring($idString);
-
$this->Noticia->id = $dados['Noticia']['id'];
-
$this->Noticia->saveField("views", ++$dados['Noticia']['views']);
-
$this->set("rows", $dados);
-
}
Ou seja, setando $this->Noticia->id com o que vem do findByIdstring. E mandando só o views atualizado para o banco.
Bom pessoal, é isso... Espero que isso resolva os problemas de alguém... Qualquer dúvida, comentem!
Abraços...
2 Comentários »
RSS feed for comments on this post · URI do TrackBack
Este site é escrito por Tulio Faria, analista de sistemas, apaixonado por web, jogos e por qualquer cacareco tecnológico.
DaniloMiguel.net - web e alguma coisa a mais » Estou voltando… said,
Janeiro 11, 2007 @ 08:03
[...] Inclusive, essa semana travamos uma briga ferrenha com o Cake, que ele postou o resultado em seu blog, mas chegamos a um bom resultado. Tudo bem que ele com uma solução própria e eu com a minha, mas problema resolvido. [...]
Gustavo Gonçalves said,
Janeiro 11, 2007 @ 10:41
Outra forma seria usar o \"find\" ao invés do \"findBy\". No caso do array(\'id\',\'views\') você listaria os demais campos que precisam ser retornados do banco de dados.