Symfony 1.0, la guía definitiva

8.3. Las clases del modelo

El esquema se utiliza para construir las clases del modelo que necesita la capa del ORM. Para reducir el tiempo de ejecución de la aplicación, estas clases se generan mediante una tarea de línea de comandos llamada propel-build-model.

> symfony propel-build-model

Nota Después de construir el modelo, es necesario borrar la caché interna de Symfony mediante el comando symfony cc para que Symfony sea capaz de encontrar los nuevos modelos.

Al ejecutar ese comando, se analiza el esquema y se generan las clases base del modelo, que se almacenan en el directorio lib/model/om/ del proyecto:

  • BaseArticle.php
  • BaseArticlePeer.php
  • BaseComment.php
  • BaseCommentPeer.php

Además, se crean las verdaderas clases del modelo de datos en el directorio lib/model/:

  • Article.php
  • ArticlePeer.php
  • Comment.php
  • CommentPeer.php

Sólo se han definido dos tablas y se han generado ocho archivos. Aunque este hecho no es nada extraño, merece una explicación.

8.3.1. Clases base y clases personalizadas

¿Por qué es útil mantener 2 versiones del modelo de objetos de datos en 2 directorios diferentes?

Puede ser necesario añadir métodos y propiedades personalizadas en los objetos del modelo (piensa por ejemplo en el método getNombreCompleto() del listado 8-1). También es posible que a medida que el proyecto se esté desarrollando, se añadan tablas o columnas. Además, cada vez que se modifica el archivo schema.yml se deben regenerar las clases del modelo de objetos mediante el comando propel-build-model. Si se añaden los métodos personalizados en las clases que se generan, se borrarían cada vez que se vuelven a generar esas clases.

Las clases con nombre Base del directorio lib/model/om/ son las que se generan directamente a partir del esquema. Nunca se deberían modificar esas clases, porque cada vez que se genera el modelo, se borran todas las clases.

Por otra parte, las clases de objetos propias que están en el directorio lib/model heredan de las clases con nombre Base. Estas clases no se modifican cuando se ejecuta la tarea propel-build-model, por lo que son las clases en las que se añaden los métodos propios.

El listado 8-4 muestra un ejemplo de una clase propia del modelo creada la primera vez que se ejecuta la tarea propel-build-model.

Listado 8-4 - Archivo de ejemplo de una clase del modelo, en lib/model/Article.php

class Article extends BaseArticle
{
}

Esta clase hereda todos los métodos de la clase BaseArticle, pero no le afectan las modificaciones en el esquema.

Este mecanismo de clases personalizadas que heredan de las clases base permite empezar a programar desde el primer momento, sin ni siquiera conocer el modelo relacional definitivo de la base de datos. La estructura de archivos creada permite personalizar y evolucionar el modelo.

8.3.2. Clases objeto y clases "peer"

Article y Comment son clases objeto que representan un registro de la base de datos. Permiten acceder a las columnas de un registro y a los registros relacionados. Por tanto, es posible obtener el título de un artículo invocando un método del objeto Article, como se muestra en el listado 8-5.

Listado 8-5 - Las clases objeto disponen de getters para los registros de las columnas

$articulo = new Article();
...
$titulo = $articulo->getTitle();

ArticlePeer y CommentPeer son clases de tipo "peer"; es decir, clases que tienen métodos estáticos para trabajar con las tablas de la base de datos. Proporcionan los medios necesarios para obtener los registros de las tablas. Sus métodos devuelven normalmente un objeto o una colección de objetos de la clase objeto relacionada, como se muestra en el listado 8-6.

Listado 8-6 - Las clases "peer" contienen métodos estáticos para obtener registros de la base de datos

$articulos = ArticlePeer::retrieveByPks(array(123, 124, 125));
// $articulos es un array de objetos de la clase Article

Nota Desde el punto de vista del modelo de datos, no puede haber objetos de tipo "peer". Por este motivo los métodos de las clases "peer" se acceden mediante :: (para invocarlos de forma estática), en vez del tradicional -> (para invocar los métodos de forma tradicional).

La combinación de las clases objeto y las clases "peer" y las versiones básicas y personalizadas de cada una hace que se generen 4 clases por cada tabla del esquema. En realidad, existe una quinta clase que se crea en el directorio lib/model/map/ y que contiene metainformación relativa a la tabla que es necesaria para la ejecución de la aplicación. Pero como es una clase que seguramente no se modifica nunca, es mejor olvidarse de ella.