Relations

In this chapter, we’ll explore how to work with entity relations in Remult using customers and orders as our example.

Relations

Many-to-One Relation

To create a many-to-one relation in Remult, we use the @Relations.toOne decorator. This decorator establishes a connection between the Order entity and the Customer entity, where multiple orders can be associated with a single customer.

For instance, in our project, the Order entity includes a reference to the Customer entity. The highlighted lines below in Order.ts show how this relation is defined:

shared/Order.ts
3 collapsed lines
import { Entity, Fields, Relations } from 'remult'
import { Customer } from './Customer'
@Entity('orders')
export class Order {
@Fields.integer()
id = 0
@Relations.toOne(() => Customer) // This establishes the relation
customer?: Customer
@Fields.number()
amount = 0
}

This setup creates a many-to-one relationship where each Order is connected to a Customer.

Seed Data

In the SeedData file, you can see how this relationship is leveraged. While inserting data into the Order table, the customer field is populated with a customer object that was previously inserted:

shared/SeedData.ts
4 collapsed lines
import { repo } from 'remult'
import { Customer } from './Customer'
import { Order } from './Order'
export async function seedData() {
const [c1, c2, c3] = await repo(Customer).insert([
{ id: 1, name: 'Fay, Ebert and Sporer', city: 'London' },
{ id: 2, name: 'Abshire Inc', city: 'New York' },
{ id: 3, name: 'Larkin - Fadel', city: 'London' },
])
await repo(Order).insert([
{ id: 1, customer: c1, amount: 10 },
{ id: 2, customer: c1, amount: 15 },
{ id: 3, customer: c2, amount: 40 },
{ id: 4, customer: c2, amount: 5 },
{ id: 5, customer: c2, amount: 7 },
{ id: 6, customer: c3, amount: 90 },
{ id: 7, customer: c3, amount: 3 },
])
}

This snippet shows how orders reference existing customer objects, creating a meaningful connection between the two entities.

Fetching Relational Data

When querying Order data, we can use the include option to retrieve the associated customer data. By default, relations are not automatically included in queries unless explicitly requested.

Here’s how to include the Customer info when fetching orders:

frontend/Page.tsx
const orders = await repo(Order).find({
include: {
customer: true,
},
})

This will return the Order data along with the related Customer data. If you set the include value to false, the customer field will be undefined in the result.

You can experiment by toggling the include value between true and false to observe how the results change.

Always Including a Relation

If you want the related Customer data to be automatically included in every query, you can set the defaultIncluded option when defining the relation. This ensures the relation is always loaded unless explicitly excluded:

@Relations.toOne(() => Customer, {
defaultIncluded: true,
})
customer?: Customer

This setting saves you from having to manually include the relation in each query, ensuring the related data is always available when you need it.

By using relations effectively, you can create more sophisticated and connected data models, enhancing the power and flexibility of your applications built with Remult.

Here’s a polished version of the paragraph:

Relations in Remult Admin

Relations are seamlessly integrated into the Remult Admin UI. To explore how relations are displayed, simply click the “Remult Admin UI” link at the bottom.

Powered by WebContainers
Files
Preparing Environment
  • Installing dependencies
  • Starting http server