CakePHP: Usar caché en el modelo
Posted by faemino | Filed under CakePHP
Podemos aprovecharnos del sistema de caché que viene por defecto en CakePHP, pensado sobre todo para las vistas, para almacenar de forma estática en un fichero información obtenida desde el modelo para tratar de minimizar los accesos a Base de Datos.
Trataré de explicarme mediante un ejemplo.
Pongamos un modelo News que tiene un método getLastNews que obtiene las últimas noticias creadas:
class News extends AppModel {
var $name = 'News';
function getLastNews(){
$find_params = array('limit' => 5, 'order' => 'News.id DESC');
$this->find('all', $find_params);
}
}
El código anterior obtendría las últimas 5 noticias y cada vez que se llame a este método se genera una consulta a la Base de Datos.
Ahora haremos unas modificaciones para generar un caché con estas últimas 5 noticias:
class News extends AppModel {
var $name = 'News';
function getLastNews(){
$data = $this->_getCache('ultimas-noticias');
if ( empty( $data ) ){
$find_params = array('limit' => 5, 'order' => 'News.id DESC');
$data = $this->find('all', $find_params);
$this->_toCache('ultimas-noticias', $data);
}
return $data;
}
function _toCache($cache_file_name = null, $data = null) {
if(! $cache_file_name) return false;
if(! $data) return false;
Cache::config(null, array('engine' => 'File', 'path'=> CACHE . '/data/'));
Cache::write($cache_file_name, $data, array('duration' => 7200, 'config' => null));
return true;
}
function _getCache($cache_file_name = null){
$data = null;
if(! $cache_file_name) return $data;
Cache::config(null, array('engine' => 'File', 'path' => CACHE . '/data/');
$data = Cache::read($cache_file_name);
return($data);
}
}
El código es mejorable, como poner los métodos de acceso a caché en el app_model, pero éste nos sirve para ver de un vistazo el funcionamiento del caché.
Ahora el método getLastNews, para obtener la información comprueba si existe en el caché, usándolo si existe y en caso contrario, consultando a la Base de Datos y creándolo para el futuro.
Para profundizar en el concepto del caché, su uso y configuración lo mejor es darse una vuelta por la documentación oficial.
Esta “técnica” se complementa muy bien con la reescritura de la callback find.
Ejecutar callbacks del modelo en función de acciones del controlador
Posted by faemino | Filed under CakePHP
Una de las cosas que me he encontrado al desarrollar con CakePHP es el poder ejectuar cierto código en las callbacks (afterSave, beforeSave, afterFind, etc.) del modelo en función de la acción realizada desde el controlador. Ciertamente no había pensado en la solución que plantea teknoid al respecto:
Generar una variable y un método en nuestro app_model:
var $controllerAction = null;
function setControllerAction( $action = null ) {
if($action) {
$this->controllerAction = $action;
}
}
Que después podemos utilizar en las callbacks de nuestros modelos:
function afterFind($results, $primary = false) {
if($this->controllerAction == 'test') {
// run some code such as $this->_reformatTestData($results);
}
}
Y desde los controladores para expecificar qué acción está realizando la llamada a la callback:
$this->User->setControllerAction('test');
$this->User->find('all');
Tags: callbacks, controladores, Modelos
Containable behavior
Posted by faemino | Filed under CakePHP
Hace unos meses hablé sobre Bindable Behaviour y de que encontraba, dada su potencia, que debería formar parte del core de CakePHP. Pues, así ha sido. Renombrado a Containable Behavior, adaptado y mejorado para que su uso sea aún más sencillo.
Tags: behaviours, Containable, Modelos
Mejorar las búsquedas mediante el método find
Posted by faemino | Filed under CakePHP
He encontrado un artículo muy interesante sobre cómo mejorar el uso del método find para hacer búsquedas más precisas o mejor dicho para extender el uso de find para adecuarlo a nuestras necesidades. Una razón más de por qué es práctico cargar el mayor código posible en los modelos.
CakePHP: Mostrar un campo específico en un elemento select
Posted by faemino | Filed under CakePHP
En un mantenimiento de alta o modificación, podemos encontrarnos con que la tabla en la que estamos haciendo el mantenimiento tiene relaciones con otras tablas. Usualmente para rellenar los valores de esas tablas relacionadas,CakePHP nos muestra un elemento select con los valores de la tabla relacionada para elegir. Por defecto los valores que aparecen son los id de los registros.
Para cambiar este comportamiento y elegir el campo que más nos interese mostrar debemos añadir la siguiente linea en el código del modelo de la tabla relacionada:
var $displayField = 'nombre';
CakePHP: Diferenciar add o edit en beforeSave o afterSave
Posted by faemino | Filed under CakePHP
El código que implementemos en el método afterSave o en el beforeSave se ejecutará tanto a la hora de realizar un add o un edit. Puede ser necesario diferenciar cuando se está ejecutando una u otra acción.
Ha falta de otra opción, una manera bastante limpia de hacerlo es preguntado por la existencia o no del id en los datos recibidos por las callbacks.
if (empty($this->id)){
// Añadiendo (no modificando)
}
Tags: afterSave, beforeSave, Modelos
CakePHP: Aproximación a los behaviours
Posted by faemino | Filed under CakePHP
Mariano Iglesias dio una charla en la CakeFest‘08 sobre los behaviours. Ha puesto en su página web la presentación que utilizó para apoyarse. Una muy buena aproximación para conocer, entender y empezar con los behaviours.
Descargar PDF de la presentación (en inglés).
Tags: behaviours, Modelos
CakePHP: Uso de beforeSave y afterSave
Posted by faemino | Filed under CakePHP
Es interesante y útil la existencia, en el modelo, de los métodos (callback) beforeSave y afterSave para manipular los datos antes o después de que vayan a ser grabados en la Base de Datos.
Un detalle muy importante a la hora de implementarlos en nuestros modelos es que debemos retornar un true o un false según el resultado del código de nuestra función.
function beforeSave(){
// Código ...
return true;
}
Mirando el código de la clase model, veo que sus métodos beforeSave y afterSave retornan un true por defecto. Ahora me pregunto si en caso de que queramos retornar un true en nuestra implementación, es más correcto retornar una llamada al método padre:
return parent::beforeSave();
De esta manera nos aseguramos que si algún día estos métodos en las clases padre tienen algo más implementado que un simple return true, ese código sea ejecutado. En caso de hacer este tipo de retorno, deberemos estar pendientes de futuras versiones de CakePHP, para ver si añaden nuevo código en estas funciones base.
Tags: afterSave, beforeSave, Modelos