====== Les associations ======
===== Déclaration =====
**Forme simplifiée :**
class Product extends SActiveRecord
{
public static $relationships = array
(
'group' => 'belongs_to',
'details' => 'has_many'
);
}
Dans le cas de la forme simplifiée, la classe de destination (option ''class_name'') sera supposée porter le même nom que l'association, ou le singulier de ce nom si l'association est de type ''has_many'' ou ''many_to_many''.
**Forme standard :**
class Product extends SActiveRecord
{
public static $relationships = array
(
'group' => array
(
'assoc_type' => 'belongs_to',
'class_name' => 'Group'
),
'details' => array
(
'assoc_type' => 'has_many',
'class_name' => 'Detail'
)
);
}
Cette forme vous permet de préciser certaines options ; les options valables pour tous les types d'associations sont :
* ''assoc_type'' : le type d'association, ''has_one'', ''belongs_to'', ''has_many'', ''many_to_many'' ;
* ''class_name'' : le nom de la classe associée.
===== Types d'associations en fonction des Foreign Keys =====
{{fr:model:associations.png}}
===== Comportement des associations =====
=== Associations has_one et belongs_to ===
* Assigner un objet à une association de ce type n'entraine pas l'enregistrement de l'objet, ni du parent.
=== Collections (associations has_many et many_to_many) ===
* Ajouter un objet à une collection entraine son enregistrement, sauf si le parent n'est pas encore enregistré dans la base.
* Tous les membres non enregistrés d'une collection sont sauvés lors de l'enregistrement du parent.
===== API des associations =====
==== has_one et belongs_to ====
L'association est accessible de la même façon qu'un attribute :
* ''$record->association->attribute'' : retourne la valeur de l'attribut de l'objet associé.
* ''$record->association->target()'' : retourne l'objet associé ou null si il n'y en a pas.
* ''$record->association->is_null()'' : retourne ''true'' si il n'y a pas d'objet associé.
* ''$record->association = $otherRecord'' : assigne l'objet à associer, en extrait la PK, et l'assigne en tant que FK.
* ''$record->association->create($attributes)'' : retourne un nouvel objet associé, instancié avec ''$attributes'', et sauvé.
Exemple : une classe Thumbnail déclare un '''photo' => 'belongs_to'''. Vous pouvez utiliser l'association ainsi :
* ''echo $thumbnail->photo->filename;''
* ''$photo = $thumbnail->photo->target();''
* ''...''
==== has_many et many_to_many ====
L'association est accessible de la même façon qu'un attribute, et se comporte comme un ''SQuerySet'' :
* ''$record->collection->all()'' : permet d'itérer les objets associés.
* ''$record->collection->count()'' : retourne le nombre d'objets de la collection.
* ''$record->collection->replace(array($entities...))'' : remplace la collection existante par le tableau d'objets fournis.
* ''$record->collection->add($entity)'' : ajoute un ou plusieurs objets à la collection.
* ''$record->collection->delete($entity)'' : supprime un ou plusieurs objets de la collection.
* ''$record->collection->singular_ids($ids)'' : replace les objets de la collection par les objets dont on fournit les IDs.
* ''$record->collection->clear()'' : supprime tous les objets de la collection.
===== Options spécifiques =====
==== has_one ====
* ''foreign_key'' : spécifie la FK à utiliser ; Par défaut, cette option sera définie comme étant le nom de la classe suivie de "_id". Si donc une classe Person dispose d'une association ''has_one'', la FK utilisée sera ''person_id''.
==== belongs_to ====
* ''foreign_key'' : spécifie la FK à utiliser ; Par défaut, cette option sera définie comme étant le nom de l'association suivie de "_id". Si donc une classe dispose d'une association ''person'', la FK utilisée sera ''person_id''.
==== has_many ====
* ''foreign_key'' : spécifie la FK à utiliser ; Par défaut, cette option sera définie comme étant le nom de la classe suivie de "_id". Si donc une classe Person dispose d'une association ''has_many'', la FK utilisée sera ''person_id''.
* ''dependent'' : si définie à ''delete'', tous les objets associés seront supprimés par l'appel de leur méthode ''delete''. Si définie à ''delete_all'', tous les objets associés seront supprimés par une unique requête SQL. Si définie à ''nullify'', les associations seront rompues en mettant à NULL la FK (les objets associés ne seront donc pas supprimés).
* ''order'' : spécifie un ordre à utiliser dans le ORDER BY de la requête récupérant les objets associés, comme par exemple ''-first_name''.
==== many_to_many ====
* ''foreign_key'' : spécifie la FK à utiliser ; Par défaut, cette option sera définie comme étant le nom de la classe suivie de "_id". Si donc une classe Person dispose d'une association ''many_to_many'', la FK utilisée sera ''person_id''.
* ''association_foreign_key'' : spécifie la FK à utiliser "de l'autre côté" de l'association ; Par défaut, cette option sera définie comme étant le nom de la classe associée suivie de "_id". Si donc une classe Person dispose d'une association ''many_to_many'' avec la classe Project, la FK utilisée sera ''project_id''.
* ''join_table'' : spécifie le nom de la table de jointure à utiliser. Par défaut, cette option sera définie comme la concaténation des noms de table des 2 côtés de l'association, en respectant l'ordre alphabétique. Par exemple, dans le cas d'une association Person <-> Project, le nom de la table utilisée par défaut sera ''people_projects''.
* ''scope'' : spécifie des conditions (SQL) à respecter pour que les objects soient associés.