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:

PHP:
  1. function ler($id){
  2. $dados = $this->Noticia->findById($id);
  3. $this->Noticia->saveField("views", ++$dados['Noticia']['views']);
  4. $this->set("data", $dados);
  5. }

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:

PHP:
  1. function ver($idString){
  2. $dados = $this->Noticia->findByIdstring($idString);
  3. $dados["Noticia"]["views"]++;
  4. $this->Noticia->save($dados);
  5. $this->set("data", $dados);
  6. }

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:

PHP:
  1. function ler($idString) {
  2. $dados = $this->Noticia->findByIdstring($idString);
  3. $this->Noticia->id = $dados['Noticia']['id'];
  4. $this->Noticia->saveField("views", ++$dados['Noticia']['views']);
  5. $this->set("rows", $dados);
  6. }

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 »

  1. 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. [...]

  2. 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.

    PHP:
    1. function ler($id) {
    2. $dados = $this->Noticia->find(\'id=\\\'\'.$id.\'\\\'\',array(\'id\',\'views\'));
    3. $dados[\'Noticia\'][\'views\']++;
    4. $this->Noticia->save($dados);
    5. $this->set(\"data\", $dados);
    6. }

RSS feed for comments on this post · URI do TrackBack

Deixe seu comentário