
# Relations

Les tables se connectent via le champ [`relationship`](/fr/docs/relational-fields#relationship), qui crée un lien par clé étrangère vers une autre table. Une fois qu'une relation existe, [`lookup`](/fr/docs/relational-fields#lookup), [`rollup`](/fr/docs/relational-fields#rollup) et [`count`](/fr/docs/advanced-fields#count) dérivent des données à travers elle sans dupliquer les valeurs.

## Définir une relation

```yaml
- id: 1
  name: customer
  type: relationship
  relatedTable: Customers
  relationType: many-to-one
  displayField: full_name
  onDelete: set-null
  onUpdate: cascade
  reciprocalField: orders
```

## Cardinalités

`relationType` définit la forme du lien. Par défaut `many-to-one`.

| Cardinalité    | Signification                                                                                                 |
| -------------- | ------------------------------------------------------------------------------------------------------------- |
| `one-to-one`   | Chaque enregistrement est lié à exactement un enregistrement, et inversement.                                 |
| `many-to-one`  | Plusieurs enregistrements ici sont liés à un enregistrement de la table liée (par défaut).                    |
| `one-to-many`  | Un enregistrement ici est lié à plusieurs dans la table liée (utilise `foreignKey`).                          |
| `many-to-many` | Les enregistrements des deux côtés sont liés à plusieurs de l'autre (`allowMultiple` vaut `true` par défaut). |

## Actions référentielles

`onDelete` et `onUpdate` définissent ce qui arrive aux lignes dépendantes lorsque la ligne liée est supprimée ou que sa clé est mise à jour.

| Action      | Effet                                                           |
| ----------- | --------------------------------------------------------------- |
| `cascade`   | Propage la suppression/mise à jour aux lignes dépendantes.      |
| `set-null`  | Définit la clé étrangère à NULL sur les lignes dépendantes.     |
| `restrict`  | Empêche l'opération tant que des dépendants existent.           |
| `no-action` | Diffère la vérification ; n'effectue aucune action automatique. |

## Liens réciproques et champ d'affichage

| Propriété         | Description                                                                                                       |
| ----------------- | ----------------------------------------------------------------------------------------------------------------- |
| `reciprocalField` | Nom du champ créé sur la table liée pour le lien inverse (bidirectionnel).                                        |
| `displayField`    | Champ de la table liée affiché dans l'interface à la place de l'identifiant brut (par ex. `full_name`).           |
| `foreignKey`      | Nom personnalisé de la colonne de clé étrangère (utilisé pour `one-to-many`). Généré automatiquement lorsqu'omis. |
| `allowMultiple`   | Autorise la liaison à plusieurs enregistrements liés (par défaut `true` pour `many-to-many`).                     |
| `limitToView`     | Restreint les enregistrements liés sélectionnables à ceux visibles dans une vue nommée de la table liée.          |

## Exemple complet

Une table `Orders` reliée à `Customers`, exposant l'e-mail du client via un lookup et un total de commandes par client via un rollup :

```yaml
tables:
  - id: 1
    name: Customers
    fields:
      - { id: 1, name: full_name, type: single-line-text, required: true }
      - { id: 2, name: email, type: email, unique: true }
  - id: 2
    name: Orders
    fields:
      - { id: 1, name: amount, type: currency, currency: USD, required: true }
      - id: 2
        name: customer
        type: relationship
        relatedTable: Customers
        relationType: many-to-one
        displayField: full_name
        onDelete: restrict
        reciprocalField: orders
      - {
          id: 3,
          name: customer_email,
          type: lookup,
          relationshipField: customer,
          relatedField: email,
        }
```

Et du côté `Customers`, un rollup des montants de commandes via le lien réciproque `orders` :

```yaml
- {
    id: 3,
    name: lifetime_value,
    type: rollup,
    relationshipField: orders,
    relatedField: amount,
    aggregation: SUM,
    format: currency,
  }
```

:::callout
**Validation.** `lookup`, `rollup` et `count` sont validés au moment de la configuration : leur `relationshipField` doit nommer un véritable champ `relationship` dans la même table. Une faute de frappe ou une référence à un champ non relationnel échoue au décodage avec une erreur claire.
:::
