# `AshUi.Notification.DerivedReads`
[🔗](https://github.com/hyperbob-labs/ash_ui/blob/main/lib/ash_ui/notification/derived_reads.ex#L1)

Subscription edges for what a rendered record DERIVES: "whatever a page
reads, it subscribes to".

The relationship walk in each transport adapter subscribes a page to the
relationships actually loaded on its record. A calculation or aggregate
the view renders reads more than that: Ash loads its dependencies as hidden
internal loads, so those rows never appear on the record and the walk
never sees them. This module turns the declaration-derived read set
(`AshUi.Reload.derived_reads/2`, the same derivation the reload
contract narrows with) into subscription edges for one loaded record:

  * the first hop of a relationship read, taken from the loaded record, is
    key-matched on `destination_attribute = record[source_attribute]` and
    carries the relationship filter with the record as `parent` — the same
    precision the relationship walk registers;
  * later hops, and aggregates over unrelated resources, have no derivable
    key and subscribe at resource level (`attrs: []`);
  * a first hop the record already has loaded, with nothing beyond it, is
    left to the walk at the root, whose reload of that relationship already
    recomputes every dependent root (`Reload.dependent_roots_for_paths/2`).

Each edge reloads `prefix ++ [field]`: the derived value itself, recomputed
by Ash with its hidden dependencies, instead of materializing the
relationship on the record.

# `edge`

```elixir
@type edge() :: %{
  key: term(),
  resource: module(),
  attrs: keyword(),
  filter: term(),
  parent: struct() | nil,
  reload_scope: [atom()]
}
```

# `edges`

```elixir
@spec edges(struct(), term(), [atom()]) :: [edge()]
```

The derived-read subscription edges of `record`, whose view load at this
level is `load_spec`, reached through relationship path `prefix`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
