> ## Documentation Index
> Fetch the complete documentation index at: https://learn.nextedy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure Many-to-Many Relationships

> Set up many-to-many (M:N) relationships in your Nextedy POWERSHEET data model so that multiple entities on each side can link to each other -- for example, system requirements linked to multiple use cases and vice versa.

export const LastReviewed = ({date}) => {
  if (!date) return null;
  const formatted = new Date(`${date}T00:00:00Z`).toLocaleDateString("en-US", {
    year: "numeric",
    month: "long",
    day: "numeric",
    timeZone: "UTC"
  });
  return <p className="mt-10 text-sm text-gray-400 dark:text-zinc-500 not-prose">
      Last reviewed on {formatted}
    </p>;
};

## Prerequisites

Before you begin, make sure you have:

* An existing data model with at least two entity types defined in `domainModelTypes`
* A Polarion link role created for the relationship (e.g., `decomposes`, `verifies`)
* Access to **Administration > Nextedy Powersheet > Data Models**

## How M:N Relationships Work

Many-to-many relationships in Powersheet use an **association entity** pattern. Unlike simpler cardinalities (N:1 or 1:N), the M:N relationship introduces an intermediate association layer between the two entity types. This affects how you configure sources and columns:

<Frame>
  <img src="https://mintcdn.com/none-17b4493f/3Zik2OH750CE3kB4/powersheet/diagrams/guides/data-model/configure-many-to-many/diagram-1.svg?fit=max&auto=format&n=3Zik2OH750CE3kB4&q=85&s=4f04d2fb9c060d5f15c7392549ba9a57" alt="diagram" style={{ width: "600px", maxWidth: "100%" }} width="600" height="180" data-path="powersheet/diagrams/guides/data-model/configure-many-to-many/diagram-1.svg" />
</Frame>

The source expand traverses two levels -- first the association collection, then the target entity -- and columns use **two-level dot-notation** to bind through the association to the target.

<Steps>
  <Step title="Define Both Entity Types">
    Ensure both sides of the relationship are defined in your data model under `domainModelTypes`. Each entity type must have a `polarionType` mapping to the corresponding Polarion work item type:

    ```yaml theme={null}
    domainModelTypes:
      UserNeed:
        polarionType: user_need
        properties:
          description:
          severity:

      SystemRequirement:
        polarionType: sys_req
        properties:
          description:
          severity:
    ```
  </Step>

  <Step title="Add the Many-to-Many Relationship">
    In the `relationships` section of your data model, add a relationship with `cardinality: many-to-many`. Define both the `direct` and `back` navigation property names:

    ```yaml theme={null}
    relationships:
      - from: SystemRequirement
        to: UserNeed
        cardinality: many-to-many
        storage: linkedWorkItems
        linkRole: decomposes
        direct:
          name: userNeeds
        back:
          name: systemRequirements
    ```

    Key properties:

    | Property      | Purpose                                                  | Example              |
    | ------------- | -------------------------------------------------------- | -------------------- |
    | `from`        | Source entity type (must match a `domainModelTypes` key) | `SystemRequirement`  |
    | `to`          | Target entity type (must match a `domainModelTypes` key) | `UserNeed`           |
    | `cardinality` | Relationship multiplicity                                | `many-to-many`       |
    | `storage`     | How links are persisted in Polarion                      | `linkedWorkItems`    |
    | `linkRole`    | Polarion link role ID (must exist in project config)     | `decomposes`         |
    | `direct.name` | Forward navigation property (from source to target)      | `userNeeds`          |
    | `back.name`   | Reverse navigation property (from target to source)      | `systemRequirements` |

    <Warning title="Navigation property naming convention">
      Use **plural camelCase** names for M:N navigation properties (e.g., `userNeeds`, `systemRequirements`). The association entity Powersheet creates automatically derives its singular form from this name. If you use a singular name, the two-level dot-notation in columns will not resolve correctly.
    </Warning>
  </Step>

  <Step title="Configure the Source Expansion">
    In your sheet configuration, set up a two-level expand in the `sources` section. The first level expands to the association collection, and the second level expands to the actual target entity:

    ```yaml theme={null}
    sources:
      - id: user_needs
        model: rtm
        query:
          from: UserNeed
        expand:
          - name: systemRequirements
            expand:
              - name: systemRequirement
    ```

    This two-level expand is what distinguishes M:N from other cardinalities:

    * **Level 1** (`systemRequirements`) -- navigates to the association entity collection
    * **Level 2** (`systemRequirement`) -- navigates from each association to the actual target entity

    <Tip title="The singular form is automatic">
      The second-level expand name (`systemRequirement`, singular) is derived automatically from the navigation property name (`systemRequirements`, plural). You do not define this singular name in the data model -- Powersheet generates it from the association entity pattern.
    </Tip>
  </Step>

  <Step title="Configure Columns with Dot-Notation">
    In the `columns` section of your sheet configuration, use the two-level dot-notation to bind through the association entity to the target:

    ```yaml theme={null}
    columns:
      title:
        title: Title
        hasFocus: true
      systemRequirements.systemRequirement:
        title: System Requirement
        list:
          search:
            - objectId
            - title
          createNew: true
      systemRequirements.systemRequirement.title:
        title: SysReq Title
        hasFocus: true
    ```

    The column bindings follow this pattern:

    * **`systemRequirements.systemRequirement`** -- a multi-item reference picker that lets users link and unlink target entities through the association
    * **`systemRequirements.systemRequirement.title`** -- a read-only display of the linked entity's `title` property (extend the dot-notation with any target property)

    The `list` block on the reference picker column configures the search dialog:

    * `search` -- which fields to search when filtering candidates
    * `createNew: true` -- allows creating new target entities directly from the picker

    <Warning title="Second linked entity column requires `multiItem: true`">
      When a sheet has two different entity types linked to the same parent (e.g., design outputs and design verifications both linked to system requirements), the second linked column must declare `multiItem: true` in the sheet configuration. Without this flag, only the first linked column renders correctly. This is a common first-time setup issue.
    </Warning>
  </Step>

  <Step title="Verify the Configuration">
    After saving your data model and sheet configuration:

    1. Open a Polarion LiveDoc or Wiki page that uses this sheet configuration
    2. Expand a row in the sheet -- you should see the linked entities appear as child items through the association
    3. Click the reference picker cell to open the search dialog and verify you can link and unlink target entities
    4. Confirm that read-only columns (e.g., `systemRequirements.systemRequirement.title`) display the correct values from linked entities

    You should now see M:N relationships rendered in your sheet with a multi-item reference picker. Each source entity can link to multiple targets, and each target can be linked from multiple sources.
  </Step>
</Steps>

## Cardinality Comparison

For reference, here is how M:N compares to other cardinality types across the three configuration layers:

| Cardinality | Model                                                        | Source expand                                                 | Column binding                         | UI behavior                   |
| ----------- | ------------------------------------------------------------ | ------------------------------------------------------------- | -------------------------------------- | ----------------------------- |
| **N:1**     | `cardinality: many-to-one`, `direct.name: chapter`           | `- name: chapter`                                             | `chapter`, `chapter.title`             | Single-value reference picker |
| **1:N**     | Reverse of N:1, `back.name: userNeeds`                       | `- name: userNeeds`                                           | `userNeeds`                            | Child rows (new sheet level)  |
| **M:N**     | `cardinality: many-to-many`, `back.name: systemRequirements` | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker   |

<Note title="Association entities are managed automatically">
  Powersheet creates and manages the intermediate association entities for M:N relationships. When you unlink two entities, Powersheet removes the association but preserves both linked entities. Deleting an entity removes all its association links as well.
</Note>

## See Also

* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- general relationship configuration for all cardinality types
* [Create Bidirectional Links](/powersheet/guides/data-model/create-bidirectional-links) -- setting up `direct` and `back` navigation properties
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) -- source and expand configuration reference
* [Configure Multi-Item Column](/powersheet/guides/sheet-configuration/configure-multi-item-column) -- detailed multi-item column setup
* [Data Model Reference](/powersheet/reference/data-model/index) -- complete data model property reference

***

<LastReviewed date="2026-07-02" />
