Relations
Les relations définissent comment les collections sont connectées au niveau de la base de données. Elles permettent à Rebase de :
- Rendre les champs de sélection de relation dans les formulaires d’entité
- Résoudre les entités liées lors de l’affichage des aperçus
- Générer les contraintes de clé étrangère dans le schéma Drizzle
- Supporter les comportements de suppression/mise à jour en cascade
Les relations peuvent être définies soit en ligne dans la propriété, soit explicitement dans le tableau relations d’une collection :
1. Relations en Ligne (Recommandé)
Section intitulée « 1. Relations en Ligne (Recommandé) »Vous pouvez définir la relation directement sur la propriété. Le framework extrait automatiquement celles-ci dans le tableau relations[] de la collection au moment de la normalisation, de sorte que vous n’avez plus besoin d’une entrée relations[] distincte pour les propriétés.
const postsCollection: EntityCollection = { slug: "posts", name: "Posts", table: "posts", properties: { title: { type: "string", name: "Title" }, content: { type: "string", name: "Content", multiline: true }, author: { type: "relation", name: "Author", target: () => usersCollection, cardinality: "one", direction: "owning", localKey: "author_id" } }};2. Tableau de Relations Explicite
Section intitulée « 2. Tableau de Relations Explicite »Pour les cas d’utilisation avancés ou lorsqu’une relation ne correspond pas directement à un champ de formulaire, vous pouvez la définir dans le tableau relations :
const postsCollection: EntityCollection = { slug: "posts", name: "Posts", table: "posts", properties: { title: { type: "string", name: "Title" }, content: { type: "string", name: "Content", multiline: true }, author: { type: "relation", name: "Author", relationName: "author" } }, relations: [ { relationName: "author", target: () => usersCollection, cardinality: "one", localKey: "author_id" } ]};Types de Relations
Section intitulée « Types de Relations »Un-à-Un / Plusieurs-à-Un
Section intitulée « Un-à-Un / Plusieurs-à-Un »Une clé étrangère sur cette table pointe vers la clé primaire d’une autre table.
relations: [ { relationName: "author", target: () => usersCollection, cardinality: "one", // This entity has ONE author direction: "owning", // The FK is on THIS table localKey: "author_id" // Column on the posts table }]Ceci crée : posts.author_id → users.id
Un-à-Plusieurs (Inverse)
Section intitulée « Un-à-Plusieurs (Inverse) »La clé étrangère se trouve sur la table cible, pointant vers cette entité.
// On the Users collection:relations: [ { relationName: "posts", target: () => postsCollection, cardinality: "many", // This user has MANY posts direction: "inverse", // The FK is on the TARGET table foreignKeyOnTarget: "author_id" // Column on the posts table }]Plusieurs-à-Plusieurs (Table de Jonction)
Section intitulée « Plusieurs-à-Plusieurs (Table de Jonction) »Deux collections connectées via une table de jonction intermédiaire.
// On the Users collection:relations: [ { relationName: "roles", target: () => rolesCollection, cardinality: "many", direction: "owning", through: { table: "user_roles", // Junction table name sourceColumn: "user_id", // FK to this collection targetColumn: "role_id" // FK to target collection } }]Ceci crée :
CREATE TABLE user_roles ( user_id INTEGER REFERENCES users(id), role_id INTEGER REFERENCES roles(id), PRIMARY KEY (user_id, role_id));Propriétés de Relation
Section intitulée « Propriétés de Relation »Pour afficher un champ de relation dans un formulaire, ajoutez une propriété avec type: "relation" :
properties: { author: { type: "relation", name: "Author", target: () => usersCollection, // Target collection widget: "select" // "select" (dropdown) or "dialog" (full picker) }}
Lors de l’affichage d’un aperçu (comme dans une cellule de tableau ou une puce de référence), Rebase gère automatiquement l’hydratation :

Jointures Multi-Sauts
Section intitulée « Jointures Multi-Sauts »Pour les relations complexes qui traversent plusieurs tables, utilisez joinPath :
// Users → Permissions through Rolesrelations: [ { relationName: "permissions", target: () => permissionsCollection, cardinality: "many", joinPath: [ { table: "user_roles", on: { from: "id", to: "user_id" } }, { table: "roles", on: { from: "role_id", to: "id" } }, { table: "role_permissions", on: { from: "id", to: "role_id" } }, { table: "permissions", on: { from: "permission_id", to: "id" } } ] }]Jointures de Clés Composites
Section intitulée « Jointures de Clés Composites »joinPath: [ { table: "customers", on: { from: ["company_code", "region_id"], // Multiple columns to: ["code", "region_id"] } }]Règles de Cascade
Section intitulée « Règles de Cascade »Contrôlez ce qui se passe lorsque les entités liées sont mises à jour ou supprimées :
relations: [ { relationName: "author", target: () => usersCollection, cardinality: "one", localKey: "author_id", onDelete: "cascade", // Delete posts when user is deleted onUpdate: "cascade" // Update FK when user ID changes }]| Action | Comportement |
|---|---|
"cascade" | Propager le changement aux lignes liées |
"restrict" | Empêcher l’opération si des lignes liées existent |
"no action" | Idem restrict (reporter à la vérification de contrainte) |
"set null" | Définir la colonne de clé étrangère à NULL |
"set default" | Définir la colonne de clé étrangère à sa valeur par défaut |
Récupération des Relations dans le SDK
Section intitulée « Récupération des Relations dans le SDK »Lors de l’interrogation de données via le SDK client Rebase, les relations ne sont pas incluses par défaut. Utilisez la méthode include() pour demander les entités liées en même temps que les données primaires.
Inclure des relations spécifiques
Section intitulée « Inclure des relations spécifiques »const { data } = await client.data.articles .include("author", "categories") .find();Inclure toutes les relations
Section intitulée « Inclure toutes les relations »const { data } = await client.data.articles .include("*") .find();Utilisation de la syntaxe des paramètres
Section intitulée « Utilisation de la syntaxe des paramètres »const { data } = await client.data.articles.find({ include: ["author", "categories"]});Structure de la réponse
Section intitulée « Structure de la réponse »Lorsqu’elles sont incluses, la réponse contient à la fois la clé étrangère scalaire et l’objet de relation hydraté :
const { data } = await client.data.articles .include("author") .find();
for (const article of data) { // Scalar FK — always present article.values.author_id; // "uuid-1234"
// Hydrated relation — only present when included article.values.author?.name; // "Jane Doe"}Les noms de relation passés à
include()doivent correspondre aurelationNamedéfini dans le tableaurelationsde la collection.
Pour la référence complète du constructeur de requêtes (filtrage, tri, pagination, temps réel), consultez la documentation du SDK client.
Interface de Relation Complète
Section intitulée « Interface de Relation Complète »interface Relation { relationName?: string; target: () => EntityCollection; cardinality: "one" | "many"; direction?: "owning" | "inverse"; inverseRelationName?: string; localKey?: string; foreignKeyOnTarget?: string; through?: { table: string; sourceColumn: string; targetColumn: string; }; joinPath?: JoinStep[]; onUpdate?: "cascade" | "restrict" | "no action" | "set null" | "set default"; onDelete?: "cascade" | "restrict" | "no action" | "set null" | "set default"; overrides?: Partial<EntityCollection>; validation?: { required?: boolean };}Étapes Suivantes
Section intitulée « Étapes Suivantes »- Règles de Sécurité — Sécurité au Niveau des Lignes
- Propriétés — Référence des types de propriétés