Recipes
Model a Relationship and Its Reverse Lookup
Store one owning reference and expose a bounded virtual reverse lookup.
The relationship is the source of truth. The join is a read-time view of documents that point back to the current entry.
Store an author relationship on posts and expose the author's posts through a virtual join field.
Use this when
- connect posts to authors
- show every post written by a user
- create a reverse relationship
- model one-to-many content
Dyrected concepts
relationship, join, relationTo, depth
Additional packages: No additional packages.
Complete recipe
This is the canonical source compiled and behavior-tested by @dyrected/knowledge.
import { defineCollection, defineJoinField, defineRelationshipField, defineTextField } from "@dyrected/core";
export const Users = defineCollection({
slug: "users",
auth: true,
fields: [
defineTextField({ name: "name", label: "Name", required: true }),
defineJoinField({
name: "posts",
label: "Posts",
collection: "posts",
on: "author",
limit: 20,
}),
],
});
export const Posts = defineCollection({
slug: "posts",
fields: [
defineTextField({ name: "title", label: "Title", required: true }),
defineRelationshipField({
name: "author",
label: "Author",
relationTo: "users",
required: true,
}),
],
});Decisions and cautions
- Keep the
join.onname synchronized with the target relationship field. - Bound large joins with
limitand make the owning relationship efficient to filter. - Choose relationship depth per view; eager hydration can multiply payload and query cost.
- Define deletion behavior at the application level. A reverse join alone does not imply cascade deletion.
Use hasMany on the owning relationship for many-to-many references; do not add a second independently writable relationship merely to simulate the reverse side.