feat(Data model): #3591678 Coalesce reference fields consumed only through nested objects
Follow-up to !1112 (merged) (notes 1200321 / 1200324).
What
When a reference field has no directly-picked value and multiple references descend through it into the same bundle on different final fields, Coalescer::coalesce() merges them into one reference-only FieldObjectPropsExpression:
ℹ︎␜entity:node:article␝uid␞␟{mail↝entity␜␜entity:user␝mail␞␟value,name↝entity␜␜entity:user␝name␞␟value}buildReferencePayload() descends such objects, so the runtime payload is identical to the separate references (a nested entity object with __type) — a storage normalization, not a behavior change. The SameFieldMustBeCoalesced validator flags the un-coalesced form.
Testing
-
composer run phpunit -- tests/src/Unit/CoalescerTest.php -
composer run phpunit -- tests/src/Kernel/Entity/JavaScriptComponentUpdateFromClientSideTest.php -
composer run phpunit -- tests/src/Kernel/Config/JavaScriptComponentValidationTest.php -
composer run phpunit -- tests/src/Kernel/Plugin/Canvas/ComponentSource/JsComponentTest.php --filter testContentEntityReference -
composer run lint(PHPCS + PHPStan)
AI usage
Implemented with Claude Code (Claude Opus 4.8). Human-reviewed.
Edited by Christian López Espínola