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 type that references exactly one record on another model. It is the core building block for relationships between models in Planhat.

  • You pick the target model when you create the field. The target cannot be changed afterwards.

  • An association can be marked primary, which gives the record master-detail semantics (it belongs to the record it points to) and builds a hierarchy. If that hierarchy reaches a Company, portfolio permissions also apply along the path; there does not have to be a Company at the top.

  • For many-to-many relationships, you do not add several association fields. You create a junction model, a custom model with two associations. (Many-to-one needs only a single association field on the child, pointing to the parent.)

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

  • The association field

  • Primary and regular associations

  • Many-to-many: junction models

  • Legacy array fields

  • Displaying associated data

  • Limits

Introduction

Records rarely stand alone. An enduser belongs to a company, and a task often belongs to a project. Associations are how you express those relationships between models in Planhat, including custom models you define yourself.

Planhat's association model is single-valued at its core: one association field references one record. Richer relationships are built up from that primitive rather than from many-valued fields.

Many-to-many is handled explicitly, through a junction model, which keeps the relationship visible, queryable, and permission-aware.

This article covers the association field, the difference between primary and regular associations, and when to move from a single association to a junction model. For the developer view of association fields, see [Custom Models API].

The Association Field

An association is a field type. Like any other field, you add it to a model and give it a name. Two things are specific to associations:

  1. You select a target model, the model whose records this field will reference.

  2. You choose whether the association is primary (covered in the next section).

An association field references exactly one record on the target model. It is the core relationship primitive in Planhat.

To add one:

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

  2. Select the target model. This is the model the field points to: the field lives on a record of the base model and references a record on the target model.

  3. Set whether the association is primary.

  4. Save the field.

The target model cannot be changed once the field is created. If you need a different target, create a new association field.

Screenshot: the association field editor, with the target-model picker and the "primary" toggle.

Primary and Regular Associations

Every association is either primary or regular. A model can have zero, one, or several associations, and marking one primary is optional.

A primary association gives the record master-detail semantics: the record is treated as belonging to the record it primarily associates with (its master). Chaining primary associations builds a hierarchy. This holds regardless of what sits at the top of that chain; there does not have to be a Company above it, and marking an association primary does not put one there.

Because the record belongs to its master, orphan prevention applies: a record on a model with a primary association cannot be created without associating it to an existing parent record, so a detail record cannot exist without its master.

One further behaviour is specific to Company. If a chain of primary associations happens to lead all the way up to a Company:

  • Portfolio permissions apply along that path. Access flows down the chain. For example, a custom model with a primary association to Enduser, where Enduser has its own primary association to Company, inherits portfolio permissions from that Company. A hierarchy that does not reach a Company still has master-detail semantics, it just does not inherit portfolio permissions.

A regular association records a relationship without master-detail semantics, and so without placing the record on a path to Company or inheriting the permissions above.

Screenshot: a custom model whose primary association resolves up to a Company, with portfolio permissions inherited along the path.

Many-to-Many: Junction Models

An association field references one record. When a relationship runs in both directions, many records to many records, you do not add multiple association fields to represent it. You create a junction model.

A junction model is nothing special: it is just a custom model with two association fields, each pointing to a different model. It sits between the two models and records the relationship, one row per pair. Because the junction is itself a model, the relationship can carry its own fields (for example a Role, or Start and End dates), and it works with formulas, joined tables, and permission paths.

To set one up:

  1. Create a custom model for the relationship (for example "Partner Account" or "Stakeholder").

  2. Add an association field pointing to the first model, and a second association field pointing to the second model.

  3. Add any fields the relationship itself needs, such as a Role or Start and End dates.

  4. Create one record per pair to record each relationship.

Common examples:

  • 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).

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, such as "team members" or "endusers" on a Company. These still work for simple cases, but they are not full associations. They do not provide bidirectional display or the association capabilities described above (primary paths, permission inheritance, junction metadata). For a real relationship between models, use an association field or a junction model rather than an array field.

Displaying Associated Data

You can surface a record's associated data on its profile and previews, and pull an associated model's fields into data tables as joined columns. See [Joined tables] and the profiles section of [Creating and managing custom models].

Joins pull down the association path only, from a parent model into the records that reference it. Surfacing a parent's child records the other way (for example, listing all Conversations that reference a given Enduser as columns) is not supported.

Limits

An association is a field, so it counts toward a model's fields. Keep the number of association fields on a single model small; a model carrying close to ten associations may be a sign the relationship should be modelled as a junction instead. The number of custom models a tenant can create depends on its plan; see [Custom model package limits].

Did this answer your question?