Skip to content

Relationship inheritance & OWNED editing

When you build a view that pulls in fields from a related entity (e.g. a Customer view showing the customer's Address.street), SchemaStack treats those fields intelligently:

  • The widget type, label, and validation rules are inherited from the entity's canonical view — set them once on Address and every view that pulls in Address fields renders them the same way.
  • You can opt to edit related rows inline ("OWNED" mode) — change the address from inside the customer view, without leaving the table. SchemaStack enforces who's allowed to do that and blocks it when sharing the related row with other parents would cause silent side effects.

This page explains how it works and how to configure it.

Canonical view per entity

Every entity in SchemaStack has exactly one canonical view — the source of truth for that entity's display configuration (widget types, labels, widget options, inline-edit fields).

When a table is imported via schema sync, SchemaStack creates a default view for it and marks that view canonical. If you create additional views for the same entity, they inherit display configuration from the canonical view by default — so a "DATE" widget you set on CourseYear.year_value in the canonical view shows up as a DATE widget in every other view that pulls in year_value, including views displaying it through a relationship.

Overriding inheritance per view

Each inheritable property can be overridden per view. In the column properties panel, fields with an inheritance source show a small badge:

Inherited from CourseYear.year_value · Override

Click Override to set a custom value just for this view. The badge switches to:

Overridden · Reset to inherited

Click Reset to inherited to drop the override and resume following the canonical view.

The properties that participate in inheritance:

PropertyInherited fromOverride scope
Widget typeCanonical view's columnPer ViewColumn
Display nameCanonical view's columnPer ViewColumn
Widget optionsCanonical view's columnPer ViewColumn
Inline-edit fieldsCanonical view's columnPer ViewColumn
Constraints / rulesEntity-level (locked, always apply)Add view-level rules on top

Constraints defined at the entity level are always enforced — you cannot disable them per view. You can only add view-level rules that layer on top.

Relationship types

When you create a relationship column from an entity, you pick the shape of the relationship:

ShapeMeaning
Many-to-oneThis row references one related row; many rows can reference the same target.
One-to-oneEach row links to at most one related row; each related row is referenced from at most one row here.
Many-to-manyEither side can link to multiple rows on the other side via a join table.
One-to-manyInverse of many-to-one — read-only display of rows that reference this one.

One-to-one is implemented as a many-to-one with a UNIQUE constraint on the FK column at the database level — but SchemaStack tracks the intent so the UI treats it as 1:1.

Ownership

Each relationship has an isOwned flag:

  • Owned — the related row exclusively belongs to the parent. Editing the related row from the parent view is safe, because no other parent references it. (Typical: Customer→Address, User→Profile, Order→Shipment.)
  • Shared — the related row is referenced by multiple parents. Editing it from one parent would silently affect the others. (Typical: Order→Country, Product→Category.)

Defaults:

  • 1:1 → owned (you usually want this)
  • M:1 → shared (you almost always want this)
  • M:M, 1:M → never owned (semantically meaningless to "own" a many-side)

You can flip the default in the picker when creating a relationship column.

Edit modes for relationship columns

A relationship column can be edited in one of three modes (set in the column properties panel under Edit Mode):

Reference (the default for shared relationships)

Picking a value changes which row is referenced (the FK). The related row itself is not modified.

"Switch this customer's country from France to Germany."

Owned (the default for 1:1 owned relationships)

Editing changes the field on the related row directly. The FK is unchanged.

"Change the street on this customer's address."

The OWNED option is only enabled when every hop in the relationship path is owned. For multi-hop columns (e.g. Customer → Address → Geolocation), all hops must be marked owned. If any hop is shared, OWNED is disabled with a message naming the offending hop:

OWNED edit blocked — relationship country is shared. Editing through it would affect other rows that reference the same target.

Association (M:M)

Add or remove links in the join table without modifying either endpoint row.

Permissions

OWNED edits write to a row in a different table than the one the source view exposes. SchemaStack checks permissions against the terminal entity, not the source view — so reading the customer view does not imply permission to edit the address. The user needs EDIT_ROW on the entity whose row is actually being modified.

What happens on save

When you save an OWNED edit, SchemaStack:

  1. Walks the relationship path to find the actual row to update (one query per hop, following FK values through real data).
  2. Verifies every hop in the path is owned.
  3. Checks you have permission on the target entity.
  4. Validates the new value against the target column's constraints.
  5. Updates the related row.
  6. Refetches the source row so the table reflects the joined update immediately.
  7. Broadcasts a terminal.row.edited event so other open views joining the target entity refresh.

If the relationship path passes through a row that hasn't been created yet (e.g. the customer has no Address row), SchemaStack returns a clear error naming the missing intermediate — you can create that row first and try again.

See also

SchemaStack Documentation