miércoles, 6 de junio de 2007

De Behavior a Helper

Llevo todo el día peleandome con lo que iba a ser un Behavior y ha acabado siendo un Helper.

En principio, yo quería hacer un Behavior capaz de "unificar" los resultados de un modelo con una asociacion BelongsTo. En concreto, se trata de unos Recursos que pueden pertenecer a una Categoría. Lógicamente Recursos tiene un campo categoria_id como foreign key.

De cara al usuario lo que tiene sentido, lógicamente, es que aparezca la etiqueta de la categoría en el listado de recursos o en la ficha, y no su id.

Por otra parte, había escrito un Helper para generar tablas (bastante flexible, ya lo colgaré cuando lo pula un poco más y le haga una documentación) a partir del resultado de un FindAll para un único modelo.

Sin embargo, la cosa se complica un poco si hay asociaciones, por lo que me interesaba "aplanar" el resultado. Es decir, que la etiqueta de la categoria apareciese como si fuese un campo de Recurso.

Empecé como behavior que se ejecutaba en afterFind, pero cuando conseguí que funcionase me dí cuenta de que daba más problemas que soluciones. Sobre todo porque, como comenté en el post sobre las precauciones con los callbacks, cualquier operación de Find lo llamaba.

Sin embargo, reflexionando un poco pensé que no tenía mucho sentido transformar los datos en el modelo para lo que era básicamente un problema de presentación. Es decir, que lo mejor sería crear un helper que tome el array de datos pasados a la vista y los reorganice en la forma deseada.

Ahora tengo dos Helpers:

  • joinTable: toma un array de modelos generado por un FindAll y fusiona los modelos en uno solo, para simplificar la visualización de los datos. Le puedo indicar qué campos de los modelos asociados tiene que unir, así controlo los datos que pasan.
  • simpleTable: toma un array de modelos (pasado directamente o preparado por joinTable) y genera una tabla con ellos, pudiendo configurar cosas como el orden de columnas, columnas para ordenar, etiquetas, acciones, y otras cosas.

La verdad es que no funcionan mal, aunque hay que pulir el código para que sea más legible y elegante y también para que haga un par de cosas que me faltan, como poder poner la columna acciones en el sitio que yo quiera.

4 comentarios:

Anónimo dijo...

Buenos días, Fran

Dicen algunos que "No es necesario un helper para eso. La capa de abstracción de los
modelos lo hace por ti."

Creo haber entendido la solución que propones y voy a empezar a implementarla.

Por otra parte, ¿qué opinas de esa afirmación? Estoy buscando en Internet pero no he conseguido encontrar nada.

Por cierto, trabajo en la 1.1 de Cake y estoy pensando en pasarme a la 1.2 y ver qué parte puedo aprovechar de lo que he hecho.

Un saludo

jordicakephp@gmail.com

Frankie dijo...

Pues con la perspectiva del tiempo te puedo decir que este artículo debería borrarlo. Es de los primeros que escribí y entonces intentaba plegar Cake a mis preconcepciones, en lugar de intentar ver mis problemas en términos de lo que Cake hace y cómo lo hace.

Lo único que hay que saber es que los modelos en CakePHP te devuelven los datos con una estructura diferente según sean modelos primarios o relacionados.

El "problema" surge cuando queremos usar la misma vista para mostrar arrays de modelos (resultado de un find) que para mostrar modelos relacionados. La estructura es ligeramente distinta. Pero creo que es mejor tratarlos de forma diferente.

Anónimo dijo...

Muchas gracias, Fran

Pues creo que tengo un problema. Tengo una vista en la que quiero imprimir un listado de notas de prensa. Las notas de prensa están relacionadas con empresas; es decir, Notaprensa belongsTo Empresa y Empresa hasMany Notaprensa.

Como quiero que en este listado aparezca el nombre de la empresa, y no su identificador, había pensado en una solución como la que propones en este post. Y creo que es la correcta. En este ejemplo que progongo, ¿se te ocurre alguna forma de imprimir el nombre de la empresa, y no su identificador, sin hacer uso de ningún helper?

Gracias de antemano y un saludo Fran

jordicakephp@gmail.com

Frankie dijo...

A ver...

¿has probado simplemente a hacer un debug($data) para ver qué datos tienes disponibles en el array de datos? Lo más seguro es que estén ahí.