Now let's define the Delivery model with a relationship to IcecreamOrder. The key is using LightIcecreamOrder as the field type - this creates an embedded reference that stores the essential order data directly in the delivery document.
Let's understand the key relationship pattern:
🔗field([LightIcecreamOrder], { minlength: 1 })
This defines a one-to-many relationship by embedding an array of LightIcecreamOrder. The "Light" version contains only essential fields (serveType, size, toppings, status) - perfect for embedding without duplicating entire documents.
📦Embedded vs Referenced
By embedding LightIcecreamOrder, the delivery document contains all necessary order info without additional database queries. This is ideal for data that's read together frequently.
Add dictionary entries for the Delivery model:
Now let's implement the service layer with lifecycle hooks. When a delivery is created, all associated orders should be marked as finished:
Key service patterns for related data:
🔌service<srv.IcecreamOrderService>()
Injects the IcecreamOrderService so DeliveryService can interact with orders. This enables cross-model operations.
⚡_postCreate
A lifecycle hook that runs after a delivery is created. It iterates through all linked orders and marks them as finished - perfect for cascading updates.
🚫_preUpdate
Prevents updates to deliveries by throwing a Revert error. Once a delivery is created, it becomes immutable - ensuring data integrity.
Now let's create the Template component for selecting related orders. The Field.Children component is designed specifically for selecting related data:
Key features of Field.Children:
📋sliceName: Specifies which slice provides the selectable options. Here it's 'icecreamOrderInDelivery' - a slice filtered for delivery-eligible orders.
🎯initArgs: Initial arguments passed to the slice query. ["served"] filters to only show orders ready for delivery.
🎨renderOption: Custom render function for each selectable option. Shows order ID for easy identification.
Add a new slice to IcecreamOrder specifically for the delivery selection UI. This filters orders by status and serve type:
Add arguments to support serveType filtering in the byStatuses query declaration in the document.
Add dictionary entries for the new slice:
Now let's create the Unit component to display deliveries with their related orders. This shows how embedded data can be rendered together:
Notice how we iterate through delivery.icecreamOrders and render each one using the IcecreamOrder.Unit.Card component. The embedded data is immediately available without additional queries!
Create the Zone component with a modal for creating new deliveries:
The submitOption.onSuccess callback updates the local state with the finished orders, keeping the UI in sync with the database changes.
Finally, let's integrate everything into the main page using Tab components to organize orders and deliveries:
Key features of this integrated page:
📑Tab: Organizes related content into switchable panels. Users can easily navigate between orders and deliveries.
⚡Promise.all: Loads both icecreamOrder and delivery data in parallel for optimal performance.