Associations

Catégorie : Modèles
L'une des fonctionnalités les plus puissantes des modèles est de pouvoir gérer les associations entre les tables.

Il existe quatre types d'associations :
  • hasOne
  • hasMany
  • belongsTo
  • hasAndBelongsToMany
Lorsqu'un modèle est défini comme étant en association avec un autre, Cake va automatiquement récupérer les données du second modèle lorsque vous appelerez celles du premier.
Par exemple, si un Post est associé à un Auteur avec une association hasMany, l'appel de $this->Post->findAll(); vous donnera tous les posts avec tous leurs auteurs.

Si vous travaillez en utilisant les conventions de nommage de Cake, alors, la déclaration d'associations va être on ne peut plus simple, et vous pourrez même utiliser le scaffolding car l'outil détecte les associations entre les tables et affiche les formulaires correspondants.
Dans cette première partie, nous ne verrons que le cas ou vous respectez les conventions de nommage. Celles qui nous interessent sont les clés étrangères, noms des modèles et noms des tables.

Petit rappel des conventions de nommage de Cake :
  • Clés étrangères : [nom du modèle au singulier]_id. Par exemple, une clé étrangère dans la table posts se référant à l'auteur devra être appellée auteur_id.
  • Noms des tables : [nom du modèle au singulier]. Les tables correspondant aux modèles Post et Auteur s'appelleront posts et auteurs.
  • Noms des modèles : [Première lettre de chaque mot en majuscule; version au singulier du nom de la table]. Le modèle se référant à la table posts est Post, et celui se référant à auteurs est Auteur.
Si vous utilisez le scaffolding, vous devrez placer vos associations dans le même ordre que les champs des tables.

  • hasOne
L'association de type hasOne permet de définir une association de cardinalité 1,1. Par exemple, un post n'a qu'un seul auteur.
Voici un exemple de déclaration de l'association :

class Post extends AppModel
{
    var $name = 'Post';
    var $hasOne = array('User =>
                        array('className'    => 'User',
                              'conditions'   => '',
                              'order'        => '',
                              'dependent'    =>  false,
                              'foreignKey'   => 'user_id'
                        )
                  );
}
?>


Explication des différents arguments de l'association :
  • className : Le nom de la classe du modèle que vous souhaitez appeller.
  • conditions : Les conditions SQL pour que l'association ait lieu. Par exemple, vous pouvez ne vouloir récupérer l'utilisateur que si celui-ci est actif. Auquel cas vous ajouterez 'actif = 1'
  • order : L'ordre de tri des données du modèle associé
  • dependent : Si la valeur est définie à true, le modèle associé est détruit lorsque celui-ci l'est. En définissant cette valeur à true ici, si un article était supprimé, l'auteur le serait également.
  • foreignKey : nom du champ permettant d'identifier l'uplet de la table associée à récupérer.
  • belongsTo
En supposant que nous ayons deux modèles : User et Profile. dans l'User, nous allons placer un hasOne vers le Profil.
Mais dans le Profil, nous allons placer une association de type belongsTo :

class User extends AppModel
{
    var $name = 'User';
    var $belongsTo = array('Post =>
                           array('className'  => 'Post',
                                 'conditions' => '',
                                 'order'      => '',
                                 'foreignKey' => 'user_id'
                           )
                     );
}
?>


Les arguments sont les mêmes que pour l'association de type hasOne.

  • hasMany
Revenons à nos modèles Post et User.
Dans notre modèle User, nous allons rajouter l'association vers les posts.

class User extends AppModel
{
    var $name = 'User';
    var $hasMany = array('Post =>
                         array('className'     => 'Post',
                               'conditions'    => 'Post.actif = 1',
                               'order'         => 'Post.created DESC',
                               'limit'         => '5',
                               'foreignKey'    => 'user_id',
                               'dependent'     => true,
                               'exclusive'     => false,
                               'finderQuery'   => ''
                         )
                  );
}
?>


Explication des arguments :
  • className : Nom du modèle avec lequel faire l'association
  • conditions : Conditions SQL requises pour effectuer l'association
  • order : Ordre dans lequel les données devront être triées
  • limit : Nombre de données maximum qui seront retournées
  • foreignKey : Nom du champ dans le modèle distant qui est la clé étrangère pointant vers le modèle local.
  • dependent : Si la valeur est définie à true, le modèle associé est détruit lorsque celui-ci l'est. En définissant cette valeur à true ici, si un article était supprimé, l'auteur le serait également.
  • exclusive : Si défini à true, lors de la suppression, tous les uplets associés sont détruits en une seule requete, sans appel à beforeDelete.
  • findQuery : permet de spécifier une requête SQL permettant d'effectuer l'association.
  • hasAndBelongsToMany
Maintenant, supposons que vous souhaitiez ajouter des tags à vos articles. Pour cela, vous allez avoir besoin de deux table supplémentaires :  tags et posts_tags.
Il serait un peu lourd de créer deux modèles non ?
C'est pourquoi la relation hasAndBelongsToMany existe.
Elle va vous permettre de définir une table tierce faisant la jointure entre deux autres. Voici un exemple :

class Post extends AppModel
{
    var $name = 'Post';
    var $hasAndBelongsToMany = array('Tag' =>
                               array('className'    => 'Tag',
                                     'joinTable'    => 'posts_tags',
                                     'foreignKey'   => 'post_id',
                                     'associationForeignKey'=> 'tag_id',
                                     'conditions'   => '',
                                     'order'        => '',
                                     'limit'        => '',
                                     'unique'       => true,
                                     'finderQuery'  => '',
                                     'deleteQuery'  => '',
                               )
                               );
}
?>


Explication des arguments :
  • className : le nom de la classe avec laquelle vous souhaitez faire la jointure
  • joinTable : le nom de la table intermédiaire permettant de joindre les deux tables
  • foreignKey : le nom de la clé étrangère dans la table intermédiaire pointant vers la table locale.
  • associationForeignKey : le nom de la clé étrangère dans la table intermédiaire pointant vers la table avec laquelle vous souhaitez faire la jointure
  • conditions : conditions SQL requises pour effectuer la jointure
  • order : ordre dans lequel seront triées les données de la base avec laquelle vous faites l'association
  • limit : Le nombre maximum d'éléments qui seront retournés dans la table distante
  • unique : Si défini à true, les entrées multiples de la table distante seront ignorées. Généralement, cela doit être défini à true. Ainsi, si le même tag est défini plusieurs fois à un post, celui-ci ne s'affichera qu'une seule fois.
  • findQuery : Il peut être quelques fois utile de définir une requete SQL de jointure manuellement si elle est complexe. C'est ce que permet cet argument.
  • deleteQuery : Vous permet de modifier la requete SQL de suppression des jointures lors de la suppression d'un uplet de cette base.
Maintenant, si nous effectuons un find() sur un post, nous obtiendront un tableau similaire à celui-ci :

Array
(
    [Post] => Array
        (
            [id] => 2
            [user_id] => 25
            [title] => Modèles : associations
            [body] => Les associations gerées par les modèles, c'est cool !
            [created] => 2007-02-15 09:33:24
            [modified] => 2007-02-15 09:33:24
            [status] => 1
        )

    [Tag] => Array
        (
            [0] => Array
                (
                    [id] => 247
                    [tag] => CakePHP
                )

            [1] => Array
                (
                    [id] => 256
                    [tag] => Model
                )
        )
)




Identification

Statistiques

153 utilisateurs
32 articles
5 connectes

CakePHP-fr

Actualites

PHP 5.2.2 et PHP 4.4.7
L'équipe de développement de PHP ...
Poste le : 04/05/2007


Nouvelles version CakePHP
Deux nouvelles versions de Cake voient le jour ...
Poste le : 06/04/2007


PHP 4.4.6
L'équipe de développement de PHP ...
Poste le : 01/03/2007


Sortie de PHP 5.2.1
L'équipe de développement de PHP ...
Poste le : 09/02/2007


Cake 1.1.13.4450 et 1.2.0.4451alpha
PhpNut nous l'annonce aujourd'hui, les versions...
Poste le : 05/02/2007


Liens