Loads options for relation/select fields in forms.
Follows the same pattern as MishkaGervaz.Table.Web.DataLoader.RelationLoader.
Modes
:static- Load all options at once (page: false):load_more- Paginated with load more button:search- Search with pagination (single select):search_multi- Search with pagination (multi select)
Action Resolution
For master users, tries :master_read → :read_any → :read.
For tenant users, uses :read with the user's site_id as tenant.
User Override
defmodule MyApp.Form.RelationLoader do
use MishkaGervaz.Form.Web.DataLoader.RelationLoader
def load_options(field, state, opts) do
super(field, state, opts)
end
endTop-level helpers (load_all_options/4, load_paginated_options/6,
build_options/4, prepend_nil_option/2, resolve_display_field/2,
resolve_load_action/3, get_tenant/1, maybe_apply_search/2,
maybe_apply_custom_load/3, resolve_selected_fallback/7) are public
so user overrides can reuse them — they live outside the __using__
macro to avoid per-consumer compile cost.
See MishkaGervaz.Form.Web.DataLoader,
MishkaGervaz.Form.Web.DataLoader.Helpers,
MishkaGervaz.Form.Web.State, and the sibling sub-builders
RecordLoader, TenantResolver, HookRunner. The table-side
counterpart is MishkaGervaz.Table.Web.DataLoader.RelationLoader.
Summary
Functions
A resource-less field's own options: its list, its zero-arity function's list, or — for
fn state -> options end — what the form state makes of them now.
The options flattened, a grouped one labelled "Group · Label" as it reads once picked.
A record's option label, by its display_field as MishkaGervaz.Helpers.resolve_label/3 reads it:
an attribute, fn record -> label end, or fn record, state -> label end given the form state. An
attribute the record leaves nil reads as the record's id.
The options whose label holds search_term. A group {group_label, [options]} is kept whole when
its own label holds it, else with the options that do, and left out when none does.
Functions
A resource-less field's own options: its list, its zero-arity function's list, or — for
fn state -> options end — what the form state makes of them now.
The options flattened, a grouped one labelled "Group · Label" as it reads once picked.
A record's option label, by its display_field as MishkaGervaz.Helpers.resolve_label/3 reads it:
an attribute, fn record -> label end, or fn record, state -> label end given the form state. An
attribute the record leaves nil reads as the record's id.
iex> MishkaGervaz.Form.Web.DataLoader.RelationLoader.get_display_value(
...> %{id: "v-1", version_name: nil},
...> :version_name
...> )
"v-1"
The options whose label holds search_term. A group {group_label, [options]} is kept whole when
its own label holds it, else with the options that do, and left out when none does.