CakePHP: Ejecutando un query a la antigua
21.feb 2008
Envía un trackback
Hay veces que la versatilidad del framework no es suficiente según el tipo de operaciones que se quieran realizar -o el límite del desarrollador, que también influye-.
Imaginemos un objeto Post del que queremos actualizar el número de veces que se ha visitado -los típicos hits-. En CakePHP y siguiendo sus convenciones sería algo similar a lo siguiente:
$post['Post']['hits']++;
$this->Post->save($post)
Lo cual genera un SQL digno de mención por otra parte:
UPDATE `posts` AS `Post` LEFT JOIN `users` AS `User` ON (`Post`.`user_id` = `User`.`id`) SET `Post`.`id` = 1128, `Post`.`user_id` = 1, `Post`.`keywords` = '', `Post`.`status` = 1, `Post`.`status_comments` = 1, `Post`.`hits` = 413, `Post`.`slug` = 'el_titulo_de_prueba', `Post`.`rating` = '0', `Post`.`created` = '2008-02-20 13:56:05', `Post`.`modified` = '2008-02-21 10:43:50' WHERE `Post`.`id` IN (1128)
Vemos que, además de actualizar el valor de los hits, actualiza los campos de fechas, el slug, el estado del Post... y no siempre es lo conveniente.
En este caso concreto la complicación venía por el slug, puesto que si cambiaba de idioma a inglés (por ejemplo), al actualizar los hits este campo se convertía en un "probing_title" con lo que el comportamiento del UPDATE rompía los esquemas del blog, los enlaces, los rss...
A falta de más conocimiento se me ocurrió ejecutar la sentencia SQL a la vieja usanza, así que creé la siguiente función dentro del modelo post.php:
function update_hits($slug, $hits)
{
$this->query("UPDATE posts SET hits=$hits WHERE slug='$slug'");
}
La llamaremos desde la función view($slug) del controlador:
$hits = $post['Post']['hits']+1;
$this->Post->update_hits($slug, $hits);
El SQL resultante se ajusta un poco más a la realidad:
UPDATE posts SET hits=414 WHERE slug='el_titulo_de_prueba'
Lo dicho al principio, hay veces que es muy cómodo trabajar con las convenciones del framework, pero lo mejor es saber combinarlas con la vieja usanza, según necesidades.
Comentarios
Amos a ahorrar una linea y aligerar un casi nada el código... por aquello del qué dirán :D
$this->Post->update_hits($slug);
function update_hits($slug, $hits)
{
$this->query("UPDATE posts SET hits=hits+1 WHERE slug='$slug'");
}
Erm.. en la declaración de la función sobra el $hits, obviamente, bastaría con el $slug... las prisas xE
function update_hits($slug)
Estos son los pequeños detalles que diferencian a las personas que se preocupan por su código y las que no nos preocupamos tanto ;).
Escribe tu comentario
Intenta que tu comentario sea interesante y con información relevante al tema de la entrada. BBCodes disponibles:
[url=http://direccion]texto[/url], negrita: [b]texto[/b],
itálica: [i]texto[/i], subrayada: [u]texto[/u].
Para mencionar o citar a alguien (quote): [cita]texto[/cita]


