11. Relaciones en las tablas artistas y discos: error de convención

Después de crear las vistas index.thtml y add.thtml es el momento de definir las relaciones que existen en la base de datos. Según la documentación oficial de CakePHP, “una de las características más potentes es el mapeo relacional que proporciona el modelo. En CakePHP, las asociaciones manejan los enlaces entre las tablas”. Como en la base de datos discografía sólo hay dos tablas -artistas y discos- y la relación que existe entre ellas es de tipo uno a muchos -un artista puede grabar varios discos y un disco pertenece sólo a un artista-, escribimos lo siguiente en los modelos Artista y Disco.

En el modelo Artista:

class Artista extends AppModel{
   // Es una buena práctica incluir esta variable
   var $name = 'Artista';
   // Información sobre las asociaciones del modelo
   var $hasMany = array('Disco'=>array('className'=>'Disco'));
}

En el modelo Disco:

class Disco extends AppModel{
   // Es una buena práctica incluir esta variable
   var $name = 'Disco';
   // Información sobre las asociaciones del modelo
   var $belongsTo = array('Artista'=>array('className'=>'Artista'));
}

 

Escribí este código y, al escribir http://localhost/discografia/artistas, obtuve estos errores:

Query: SELECT `Disco`.`id`, `Disco`.`nombre`, `Disco`.`ano`, `Disco`.`artista_id` FROM `discos` AS `Disco` WHERE `Disco`.`artista_id` IN (1, 2, 3)

Warning: SQL Error: 1054: Unknown column ‘Disco.artista_id’ in ‘field list’ in C:\wamp\www\discografia\cake\libs\model\datasources\dbo_source.php on line 439
Warning: Invalid argument supplied for foreach() in C:\wamp\www\discografia\cake\libs\model\datasources\dbo_source.php on line 757

Esto pasó porque en el momento de crear las tablas no contemplé el hecho de que existe una relación entre ellas: tendría que haber creado una clave externa en la tabla discos, para que apuntara a la tabla artistas. Para hacer esto, hay que respetar las convenciones que establece CakePHP: todas las tablas deben tener un campo id para su clave primaria, y, como se va a utilizar una clave externa en la tabla Discos, el nombre del campo tiene que ser artista_id. Qué mejor sitio que el oficial para ver más información sobre las convenciones: http://book.cakephp.org/es/view/22/Convenciones-de-CakePHP.

Después de darme cuenta de esto, borré las tablas artistas y discos y las volví a crear. Finalmente quedaron así:

A continuación aproveché para insertar, con el comando insert, algunos registros desde el monitor MySQL y creé la vista index.thtml para la tabla discos; escribí este código, que imprimió el identificador del artista sin lanzar ningún error:

<h1>Discos de discografia</h1>
<table>
       <tr>
           <th>Disco</th>
       </tr>
       <?php foreach ($discos as $disco): ?>
       <tr>
           <td>
               <?php
                   echo $disco['Disco']['nombre'];
                   echo $disco['Disco']['artista_id'];
               ?>
           </td>
       </tr>
       <?php endforeach; ?>
</table>
Anuncios

Una respuesta

  1. Me acordaste de un error que tuve y estuve dándole vueltas un buen rato. Era los campos id, que por convención cakephp los exige y como trabajo con una herramienta case para hacer los scripts de las bases de datos, la herramienta inicialmente ‘daba error’ cuando habian tablas con el mismo nombre de atributo. Despues pude corregirlo (y que la herramienta case no tomara en cuenta eso) Y al generar el script para mi base de datos, en vez de colocar las claves foráneas como id, las colocaba con el nombre de la tabla (abreviado) y el campo id.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: