Skip to content

fix: record filter matches nothing for single-value fields - #202

Merged
ManukMinasyan merged 1 commit into
3.xfrom
fix/record-filter-single-value
Aug 18, 2026
Merged

fix: record filter matches nothing for single-value fields#202
ManukMinasyan merged 1 commit into
3.xfrom
fix/record-filter-single-value

Conversation

@ManukMinasyan

Copy link
Copy Markdown
Collaborator

Problem

Filtering a table by a single-value Record custom field returns no rows, even when matching records exist. Multi-value Record fields filter correctly.

Found while answering https://github.com/orgs/relaticle/discussions/469 (using Record fields to model people-to-people relationships).

Root cause

RecordFilter branched on allow_multiple and queried a different column per cardinality:

if ($isMultiSelect) {
    $subQuery->orWhereJsonContains('json_value', $value);
} else {
    $q->whereIn('string_value', $data['values']);   // never populated
}

RecordFieldType::configure() is FieldSchema::multiChoice() regardless of allow_multiple, so values always land in json_value. The single-value branch queried a column that is always NULL for record fields:

reports_to      string_value=NULL  json_value='["01m0aez6vjvbwnq6j46f2x53pn"]'
direct_reports  string_value=NULL  json_value='["01m0aez6v9ax794ngeenxen1mk", ...]'

Also fixed

Filter option labels rendered as escaped HTML (<div class="flex items-center gap-2"><img src="data:image/svg+xml;base64…). formatOptionWithAvatar() returns avatar markup but the SelectFilter did not allow HTML. SelectFilter has no allowHtml(), so this goes through modifyFormFieldUsing() onto the inner Select. Both interpolations already pass through e().

Test

Added a dataset-driven case in ListRecordsTest covering both cardinalities. Verified load-bearing: with the source change reverted, single-value fails and multi-value passes.

Verification

  • composer test:pest — 831 passed, 3 todos
  • vendor/bin/phpstan analyse — no errors
  • vendor/bin/pint --test — passed
  • Type coverage on RecordFilter.php — 100% (repo total is 99.4% before and after this change)
  • Walked in a real browser against a Relaticle app: the filter that returned "No people" now returns the expected row, and the dropdown shows the avatar + name

…rdinality

Record fields always persist to json_value because RecordFieldType is
declared as a multiChoice schema, but the filter branched on
allow_multiple and queried string_value for single-value fields. That
column is never populated, so filtering a single-value record field
returned no rows.

Also renders option labels as HTML. formatOptionWithAvatar() returns
avatar markup, which SelectFilter escaped by default, printing the raw
div in the dropdown.
Copilot AI lite review requested due to automatic review settings August 18, 2026 17:14

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@ManukMinasyan
ManukMinasyan merged commit a33e3a3 into 3.x Aug 18, 2026
4 checks passed
@ManukMinasyan
ManukMinasyan deleted the fix/record-filter-single-value branch August 18, 2026 17:20
ManukMinasyan added a commit to relaticle/relaticle that referenced this pull request Aug 18, 2026
Record custom fields always persist to json_value, but the table filter
queried string_value when allow_multiple was false, so filtering a
single-value record field returned nothing. The package release also
renders filter option labels as HTML instead of printing raw markup.

Upstream: relaticle/custom-fields#202
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants