Relaciones en Symfony 1.4 con Doctrine

junio 17, 2011

Una de las dificultades que podemos encontrar al utilizar el ORM Doctrine (por ejemplo, en Symfony) es configurar las relaciones entre tablas en el schema.yml que define nuestra base de datos. A modo de ejemplo, voy a mostrar los tres tipos de relaciones que podemos querer configurar:

Relaciones uno a uno

Un caso típico para este tipo de relación es el de un usuario y su perfil. Un usuario solamente tiene un perfil y un perfil solo puede pertenecer a un usuario.

User:
  tableName: user
  columns:
    id:
      type: integer(4)
      primary: true
      notnull: true
      autoincrement: true
    email:
      type: string(255)
      notnull: true
      unique: true
    password:
      type: string(45)
 
Profile:
  tableName: profile
  columns:
    user_id:
      type: integer(4)
      primary: true
      notnull: true
      autoincrement: false
    nickname: string(255)
  relations:
    User:
      class: User
      local: user_id
      foreign: id
      foreignAlias: Profile
      type: one
      foreignType: one

Con esta relación, podremos acceder al perfil de un usuario así:

$user->Profile->nickname // obtenemos el nickname del perfil del usuario

Relaciones uno a muchos:

Un ejemplo de este tipo de relación es el de los usuarios y sus números de teléfono. Un usuario puede tener varios números de teléfono pero un teléfono solo puede pertenecer a un usuario.

User:
  tableName: user
  columns:
    id:
      type: integer(4)
      primary: true
      notnull: true
      autoincrement: true
    email:
      type: string(255)
      notnull: true
      unique: true
    password:
      type: string(45)
 
Telephone:
  tableName: telephone
  columns:
    id:
      type: integer(4)
      primary: true
      notnull: true
      autoincrement: true
    user_id:
      type: integer(4)
      notnull: true
    number:
      type: string(255)
  relations:
    User:
      class: User
      local: user_id
      foreign: id
      foreignAlias: Telephones
      type: one
      foreignType: many

Para acceder a los números de teléfono de un usuario, podemos hacer:

foreach($user->Telephones as $telephone){
  echo $telephone->number;
}

Relaciones muchos a muchos

Para terminar, un caso típico de esta relación es la que podemos encontrar entre los artículos de un blog y sus etiquetas. Un artículo puede tener varias etiquetas y una etiqueta puede asignarse a varios artículos. En esta relación necesitaremos obligatoriamente una tercera tabla (article_tags) para poder relacionar la tabla articles y la tabla tags.

Article:
  tableName: articles
  columns:
    id:
      type: integer(4)
      primary: true
      notnull: true
      autoincrement: true
    title:
      type: string(100)
      notnull: true
 
Tag:
  tableName: tags
  columns:
    id:
      type: integer(4)
      primary: true
      notnull: true
      autoincrement: true
    name:
      type: string(100)
      notnull: true
  relations:
    Article:
      foreignAlias: Tags
      class: Article
      refClass: ArticleTag
 
ArticleTag:
  tableName: article_tags
  columns:
    article_id:
      type: integer(4)
      primary: true
    tag_id:
      type: integer(4)
      primary: true
  relations:
    Article:
      foreignAlias: ArticleTags
    Tag:
      foreignAlias: ArticleTags

Podremos obtener el nombre de todos los tags de un artículo de la siguiente manera:

foreach($article->ArticleTags as $article_tag){
      echo $article_tag->Tag->name;
}

¡Cualquier duda, en los comentarios!

Tags ; , , ,

2 comentarios

    Juan Ago 22, 2011

    Saludos compañero, muy buena la información q tienes. He estado trabajando con Symfony 1.4 con conexión a base de datos PostgreSQL con varios esquemas (sfPostgresDoctrinePlugin), y he presentado problemas a la hora de generar los formularios con «doctrine:generate module», dado que me arroja errores al momento de representarme los combobox que deberían tener valores (id) de tablas relacionadas 1:N , aun cuando he redefinido los métodos __toString(). Queria saber si tienes experiencia en esta area y podrias orientarme. Saludos

    Responder
    Lizethe Jun 04, 2013

    creo q explicación mas clara no existe, GRACIAS!! 🙂

    Responder

Escribe un comentario

Los comentarios son moderados y se utiliza rel="nofollow" para los enlaces.