Fix compound metadata removal without restart - #7583
Conversation
Reproduces a compound metadata field continuing to render on work forms after it is removed from the m3 profile, until the app is restarted. The failure needs the compound present in the profile at class load, which is what seeds the stale schema entry. A scalar removed the same way already disappears correctly; that case is included as a control so the compound-specific nature of the bug stays pinned. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A compound removed from the m3 profile now disappears from work forms immediately, matching how an ordinary single-value property already behaves. Flexible resources resolve compounds from the loader's attribute map at the current profile version instead of their Dry schemas. Those schemas cannot represent a removal: Hyrax::Flexibility.attributes only merges attributes in, and builds the singleton schema from the class schema, so a compound present when the class loaded survives in both for the life of the process. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Test Results 17 files ± 0 17 suites ±0 3h 39m 11s ⏱️ + 18m 49s Results for commit 86ebbab. ± Comparison against base commit e66834c. This pull request removes 442 and adds 448 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
A compound declared as a plain class attribute, on a class the m3 profile does not govern, resolves from the class schema again. The profile is authoritative only for classes it declares. Gating on flexible? alone sent every flexible resource to the loader, which answers for an unknown class with a fallback schema rather than nothing — silently dropping a compound that only the class body declares, such as the FileSet provenance case. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes a flexible-metadata edge case where removing a compound field from the active M3 profile didn’t stop it from rendering on work edit forms until the app was restarted. It does this by changing how Hyrax::CompoundSchema resolves compound declarations in flexible mode and adds a regression spec that reproduces the stale-compound behavior.
Changes:
- Add a failing regression spec demonstrating compound removal not taking effect without a restart.
- Update
Hyrax::CompoundSchemato prefer current profile-derived attribute maps for profile-governed flexible resources instead of relying on stale Dry schemas.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| spec/services/hyrax/compound_schema_profile_removal_spec.rb | Adds a regression spec covering removal of a compound field without restarting the app. |
| app/services/hyrax/compound_schema.rb | Adjusts compound resolution to use loader-provided attribute maps for the current profile when the profile governs the resource. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
A governed class whose current contexts filter out every field no longer falls back to its stale schemas, which would have resurrected the compounds the profile dropped. The loader already distinguishes the two cases: nil means it could not answer, an empty map means it answered with nothing. Testing for present? conflated them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Summary
Fix compound metadata removal without restart. If an app is booted with flexible metadata and includes compound metadata, removing the compound metadata from the m3 profile didn't take effect until restarting the app.
Details
The first commit adds a failing spec that reproduces a compound metadata field continuing to render on work forms after it is removed from the m3 profile, until the app is restarted.
The second commit fixes the bug: flexible resources now read compound declarations from the loader's attribute map at the current profile version, rather than from the resource's Dry schemas. A compound removed from the m3 profile disappears from work forms immediately, with no restart.
The Dry schemas cannot represent a removal.
Hyrax::Flexibility.attributesonly merges attributes in, and builds the singleton schema from the class schema, so a compound present when the class loaded survives in both the class and singleton schemas — foldedsubproperties:and all — for the life of the process. Ordinary single-value properties were unaffected becauseResourceForm#initializealready prunes definitions absent from the current profile; compounds bypass that prune, rendering via#compound_termsinstead.Testing
type: hashparent property with at least one member declaringavailable_on: { properties: [<parent>] }). Confirm the compound renders on a work's edit form.