Single records

Single records

Since we want to manage stock for individual products, we need a way to view a single product. Adding a get action creates a page that displays all fields for a single product.

model Product {
    actions {
        ...
        get getProduct(id)
    }
    @permission(
        expression: ctx.isAuthenticated,
        actions: [..., get]
    )
}

Now, when we deploy the schema, we can view a single proudct by its ID.

Get product tool

It also links to single products in the data table of our List products tool that we created earlier.

Linked list & get

Notice how the Stock field displays a ⓘ Missing 'list' action message? We'll fix that next.

Linking fields

Let's go deeper and explore how we can find all the stock associated with a product. Adding a list action to StockItem with product.id as input creates a link to list them.

model Product {
    fields {
        ...
        stock StockItem[]
    }
    actions {
        ...
    }
}
 
model StockItem {
    fields {
        ...
        product Product
    }
    actions {
        ...
        list listStockItems(product.id)
    }
    @permission(
        expression: ctx.isAuthenticated,
        actions: [..., list]
    )
}

Now, our single product page displays a user interface element linking to this product's relevant stock items.

Linked field

Our list of products also links to the list of stock items for each product with this one change to our schema:

Linked field in list

Putting it all together

With a few simple changes to our schema, we can now dive deeper into a single product and its related data from a list. We can also link to a list of stock items for each product's single product page, all with zero code outside of our single Keel schema.

The full schema after all these changes is below.

Schema

schema.keel
model Product {
    fields {
        name Text
        description Text?
        imageUrl Text?
        stock StockItem[]
    }
    actions {
        get getProduct(id)
        list listProducts()
        create createProduct() with (name, description?, imageUrl?, stock.quantity, stock.location.id)
    }
    @permission(
        expression: ctx.isAuthenticated,
        actions: [list, create, get]
    )
}
 
model StockItem {
    fields {
        product Product
        quantity Number
        location StockLocation
    }
    actions {
        create createStockItem() with (quantity, product.id, location.id)
        list listStockItems(product.id)
    }
    @permission(
        expression: ctx.isAuthenticated,
        actions: [create, list]
    )
}
 
model StockLocation {
    fields {
        name Text @unique
        items StockItem[]
    }
    actions {
        list listStockLocations()
        create createStockLocation() with (name)
    }
    @permission(
        expression: ctx.isAuthenticated,
        actions: [list, create]
    )
}

Next steps

Okay, we've nearly got a full stock management solution—however, we cannot yet update or delete products or stock items. Let's fix that in the next section.