Skip to content

How to define a "Has Many" reference between models

Please refer to here for general information about models.

If you define a "Has Many" reference between models, you are creating a Master/Detail relationship. You have to operate in both master and detail models:

  • Master model: define the DetailReferences node listing detail references
  • Detail model: define a reference field that points back to the master model.

Example from TasKitto:

yaml
# model PROJECT.yaml
ModelName: PROJECT
Fields:
  PROJECT_ID: String(32) not null primary key
    IsVisible: False
    DefaultValue: %COMPACT_GUID%
  PROJECT_NAME: String(40) not null
  CUSTOMER: Reference(CUSTOMER) not null
    Fields:
      CUSTOMER_ID:
  STATUS: String(12)
    AllowedValues:
      Offered: Offered
      Open: Open
      Stopped: Stopped
      Terminated: Terminated
DetailReferences:
  PHASE: PHASE

# model PHASE.yaml
ModelName: PHASE
Fields:
  PHASE_ID: String(32) not null primary key
    IsVisible: False
    DefaultValue: %COMPACT_GUID%
  PHASE_NAME: String(40) not null
  PROJECT: Reference(PROJECT) not null
    Fields:
      PROJECT_ID:
  START_DATE: Date
  END_DATE: Date
  STATUS: String(12)
    AllowedValues:
      Started: Started
      Finished: Finished
      Invoiced: Invoiced
      Killed: Killed
      Waiting: Waiting

Rendering master/detail in views

To display the master/detail relationship in the UI, define the MainTable/DetailTables node in the view:

yaml
# view Projects.yaml
Type: Data
Controller: List

MainTable:
  Model: PROJECT
  DetailTables:
    Table:
      Model: PHASE
      Controller:
        Form:
          Layout: Phases_Form

When editing a master record, detail tables appear as additional tabs in the form dialog, merged into the same tab bar as any PageBreak tabs from the form layout. For example, if the Project form layout has no page breaks, the tab bar shows [Project | Phases].

The detail grid has its own CRUD toolbar (Add, Edit, Delete) and supports double-click to open the detail record form.

Auto-built vs. explicit views

By default, when you specify only Model: PHASE, Kittox auto-builds a list view with a standard grid, toolbar, and search filter. If you need more control over the detail's columns, filters, or toolbar, you can reference an explicit view:

yaml
  DetailTables:
    Table:
      ViewName: Phases

FK field handling

When a detail form is opened from the master, the foreign key field (e.g., PROJECT in a PHASE record) is automatically:

  • Read-only in all modes (edit, view, add) — the user cannot change the master link.
  • Pre-filled when adding a new record — set to the current master record's key.

Nested details

Detail tables can themselves have detail tables:

yaml
# view Customers.yaml
MainTable:
  Model: CUSTOMER
  DetailTables:
    Table:
      Model: PROJECT
      DetailTables:
        Table:
          Model: PHASE
          Controller:
            Form:
              Layout: Phases_Form
      Controller:
        PreventAdding: False
        PreventDeleting: False
        AllowDuplicating: True

In this example, editing a Customer shows a PROJECT tab; editing a Project shows a PHASE tab.

Custom form layout for details

You can specify a form layout for the detail record dialog:

yaml
  DetailTables:
    Table:
      Model: PHASE
      Controller:
        Form:
          Layout: Phases_Form

The layout file (e.g., Phases_Form.yaml under Metadata/Views/Layouts/) controls which fields appear and how they are arranged:

yaml
# Phases_Form.yaml
Row:
  Field: PROJECT
    CharWidth: 40
Field: PHASE_NAME
Row:
  Field: START_DATE
  Field: END_DATE
  Field: STATUS

See Form for full details on form layouts and the master/detail feature.

Released under Apache License, Version 2.0.