sábado, 1 de febrero de 2014

Relaciones entre modelos en Yii


Supongamos que tenemos 3 tablas: user, city y country, relacionadas de la siguiente forma: un usuario vive en una ciudad (user tiene un campo city_id que referencia a una entrada de la tabla city), y una ciudad pertenece a un país (city tiene un campo country_id que referencia a una entrada de la tabla country).

Si en alguna vista relacionada con los usuarios queremos mostrar información referente al país del usuario, la clave está en definir relaciones. Las relaciones entre modelos se establecen mediante la función relations(), y pueden ser de 4 tipos:
  • BELONGS_TO
  • HAS_MANY
  • HAS_ONE
  • MANY_MANY

En este caso, nos basta con relaciones BELONGS_TO, pero es bueno saber el significado de cada relación y cómo ha de usarse (alguien que sepa crear y administrar bases de datos, debería saber de entrada qué significa cada relación). Para profundizar en el tema, consultar la guía.

En el modelo User debemos definir una relación BELONGS_TO con relación a la ciudad:

        public function relations()
{
return array(
  'city' = array(self::BELONGS_TO, 'City', 'city_id');
);
}

En el modelo City debemos definir otra relación BELONGS_TO con relación al país:

        public function relations()
{
return array(
  'country' => array(self::BELONGS_TO, 'Country', 'country_id'),
);
}

Con esto es suficiente, no es necesario modificar la(s) función(es) de búsqueda del modelo User para incluir joins o cosas parecidas, el Active Record de Yii se encargará de todo.

Si por ejemplo vamos a mostrar una lista de usuarios en un CGridView, en el cual accedemos a los atributos de User como $data->username o $data->email, podemos acceder a los campos correspondientes al país, mediante $data->city['country']['name'] o $data->city['country']['population'].

Personalmente, a esto último llegué por ensayo y error, pero una vez asimilado creo que no se olvida. Si por ejemplo hubiese una hipotética tercera relación, digamos que un país pertenezca a un planeta, accederíamos a la data del planeta mediante $data->city['country']['planet']['name'] (siempre que hayamos definido una relación planet en el modelo country, lógicamente).

2 comentarios:

maykol dijo...

Aun usas yii?

todoparabebes dijo...

me podrias ayudar con algo como esto que no me funciona?