Fix NestedForm falling back to the parent model when empty (#1522) - #1523
Conversation
An empty nestedform passed its inner Form a null data source, so Form::getModel() fell back to the parent model. Sub-fields then resolved their values from the model's attributes by name — and when a sub-field name collided with a model attribute holding an array (e.g. a jsonable field), rendering it (as a textarea, etc.) threw "Array to string conversion", taking down the whole form. Pass an empty array rather than null when the field has no value, so the inner form stays scoped to the nested data and never reaches the parent model. Fixes #1522 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review. Walkthrough
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to The change narrowly prevents empty nested forms from reading values from the parent model while preserving populated nested-form behavior; no actionable merge-blocking risk remains after normal checks and review. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Problem
Fixes #1522.
A
nestedformfield whose sub-field name collides with a model attribute crashes the whole form withErrorException: Array to string conversionwhen the nested form has no value — most visibly when the model attribute is a$jsonablearray.Root cause
NestedForm::init()passed the field's load value straight to the innerForm'sdata:When the field has no value,
getLoadValue()returnsnull.Form::getModel()then does:isset()isfalsefornull, so the inner form falls back to the parent model as its data source. Sub-fields then resolve their values from the model's attributes by name, so a sub-field named e.g.contentpicks up$model->content— and rendering an array value as a textarea throwsArray to string conversion, taking down the form.Fix
Scope the nested form to its own value; pass an empty array instead of
nullso it never reaches the parent model:Tests
Adds
modules/backend/tests/formwidgets/NestedFormScopingTest.php:testEmptyNestedFormDoesNotResolveSubFieldsFromParentModel— an empty nested form with acontentsub-field, on a model whose rootcontentis a jsonable array, must resolve the sub-field to empty (not the model's array). Fails without the fix ("two arrays are not identical"), passes with it.testPopulatedNestedFormStillResolvesItsOwnValues— a populated nested form still resolves its own values (the nested value wins over the colliding model attribute).Full
modules/backend/tests/widgets+modules/backend/tests/formwidgetssuites pass (85 tests).🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests