Skip to main content

Custom Associations

How records on one model reference records on another, and when to reach for a junction model.

Written by Alexander Käll

Summary

  • An association is a field that links to exactly one record on another model, the core building block for relationships in Planhat.

  • You pick the model it links to when you create the field. That can't be changed later.

  • Mark an association primary to make the record a child of the record it points to. This builds a hierarchy and, when the chain reaches a Company, applies that Company's permissions.

  • For many-to-many relationships, create a junction model instead of adding several association fields.

Who is this Article for?

  • Planhat builders/admins who set up the data model for their team (e.g. CS Ops).

Series

This article is part of a series on Custom Models:

Article Contents

Introduction

Records rarely stand alone. An End User belongs to a Company; a task often belongs to a project. Associations are how you express those relationships between models, including the custom models you define yourself. This article covers the association field, primary vs. regular associations, and when to move to a junction model.

An association field is Planhat's version of a foreign key — it stores the ID of a related record on another model. For many-to-many, a junction model is the equivalent of a join / associative table.

The Association Field

An association is a field type. You add it to a model and name it, like any field. Two things are specific to associations: you pick the model it links to, and you choose whether it's primary.

To add a association field:

  1. Go to Data Model → [your model] → Fields and create a field of type Association.

  2. Choose the model it links to. The field lives on your model's records and points to one record on that other model.

  3. Set whether it's primary (see below).

  4. Save. The linked model can't be changed later — to point somewhere else, create a new field.

Which model does the field go on?

An association links to one record, so it goes on the model that has one of the other. Ask: does each of my records have exactly one of the thing I'm linking to?

For example, if you are connecting Conversations to Deals, each conversation belongs to one Deal, but a Deal has many Conversations. So the field goes on Conversation, linking to the target model Deal. You don't add a field on the Deal to see its Conversations. Once Conversations point to their Deal, they can appear on the Deal profile in a related widget automatically.

One-to-many with a single association field: each Conversation points to one Deal, so the field lives on Conversation (the "many" side).

Diagram of a one-to-many relationship. One Deal at the top with three Conversations below, each pointing up to the Deal. The association field lives on Conversation, the "many" side, and points to the one Deal it belongs to.

Rule of thumb: put the field on the "belongs-to" side (the child), pointing at the "has-many" side (the parent).

Primary and Regular Associations

Every association is either primary or regular. Marking one primary is optional; a model can have none, one, or several associations.

A Primary association makes the record a child of the record it points to (its parent). Chaining primary associations builds a hierarchy. Two things follow:

  • Orphan prevention — a child can't be created without an existing parent, so it's never stranded.

  • Permissions (only when the chain reaches a Company) — if the chain leads up to a Company, the record inherits that Company's portfolio permissions. A chain that never reaches a Company still works as a hierarchy; it just doesn't inherit permissions.

How a primary chain carries permissions down from a Company:

Diagram of a primary association chain. A Custom record has a primary association to an End User, which has a primary association to a Company. Arrows point upward from child to parent. Permissions flow downward from the Company at the top to every record below it.

💡 Tip
Point a primary association at a Company, or at a model that itself connects to one, so the chain always reaches a Company. If it doesn't, permissions can't be applied and the record becomes visible to all internal users.

A Regular association records a relationship without making the record a child: no hierarchy, no permission inheritance.

Many-to-Many: Junction Models

An association links to one record. When a relationship runs both ways - many records to many records - don't add multiple association fields. Instead, create a junction model: a custom model with two association fields, one to each model. It sits between them, one record per pair, and can carry its own fields (a Role, Start/End dates) that work with formulas, joined tables, and permission paths.

A junction model records a many-to-many relationship as one row per pair. Here, a Buying Committee model links Deals and End Users — each record is one person on one deal, with their own Role:

Diagram of a many-to-many relationship built with a junction model. Two Deals on the left and two End Users on the right are connected through three Buying Committee records in the middle. Each junction record links one Deal to one End User and stores a Role (Decision Maker, Champion, Influencer). End User 1 is linked to both Deals, showing that one person can belong to many deals and one deal can have many contacts.

Click the image to view it enlarged

Additional common examples of Junction Models:

  • An Enduser who works across several Companies (and Companies with many such Endusers).

  • A Contact associated with several Deals.

  • Stakeholder mapping between Company, Account Contact, and Enduser, carrying a Role and Start/End dates (often mirrored from a Salesforce AccountContactRelationship).

Use a single association field for one-to-many, and a junction model for many-to-many. The difference:

Side-by-side comparison of two relationship patterns. On the left, "one-to-many": three Conversations each point up to a single Deal using one association field that lives on Conversation. On the right, "many-to-many": two Deals and two End Users are linked through Buying Committee junction records, each carrying a Role, because a Deal can have many End Users and an End User can be on many Deals.

Click the image to view it enlarged

To set one up:

  1. Create a custom model for the relationship (e.g. "Stakeholder").

  2. Add one association to each of the two models.

  3. Add any fields the relationship needs (Role, dates).

  4. Create one record per pair.

A junction only changes the shape of the relationship. It does not let you display a parent's child records back on the parent's table: joins still pull down the association path only (see Displaying associated data).

Legacy Array Fields

Some system models carry older array-style fields that hold several records (like "team members" on a Company). They still work for simple cases, but they aren't full associations - no bidirectional display, primary paths, permission inheritance, or junction metadata. For a real relationship, use an association field or junction model.

Displaying Associated Data

You can pull a linked model's fields into tables as joined columns. Joins work one direction only: a child can show fields from the parent it points to. The reverse, listing a parent's child records as columns, isn't supported.

Limits

An association is a field, so it counts toward a model's field limit. If a model is approaching ten associations, that's often a sign the relationship should be a junction instead. The number of custom models you can create depends on your plan.

Did this answer your question?