Repository navigation
Hide nested params of a hidden Hash parameter - #1016
Merged
Merged
Conversation
Children of a Hash parameter arrive as separate parent[child] entries that do not carry the parent's documentation, so hidden: true on the parent left orphaned query parameters in the document. Skip entries nested under a hidden parent as well.
numbata
force-pushed
the
issue-1015-hidden-hash-children
branch
from
November 4, 2026 17:40
257ced7 to
450c74b
Compare
numbata
marked this pull request as ready for review
November 4, 2026 17:44
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues remain, and the change includes regression coverage for filtering nested parameters under hidden Hash roots.
No open issues 🎉
What changed in this PR
This pull request fixes Swagger documentation generation so hiding a Hash parameter also hides its nested query parameters, preventing orphaned child fields from appearing.
Changes:
- Tracks hidden top-level parameters and filters their nested descendants.
- Adds regression coverage for nested and deeply nested Hash parameters.
- Documents the fix in the changelog.
| File | Description |
|---|---|
spec/issues/1015_hidden_hash_children_spec.rb |
Verifies hidden Hash children are excluded while visible parameters remain. |
lib/grape-swagger/endpoint.rb |
Filters hidden Hash roots and their nested parameters during documentation generation. |
CHANGELOG.md |
Documents the hidden nested-parameter fix. |
Review effort: Lite
Danger ReportNo issues found. |
Deciding whether a parent is hidden now goes through the same token owner aware evaluation as route visibility, so a hidden: proc taking the token owner no longer raises. Specs cover prefix siblings, array parents, proc-hidden parents and the body definition.
Hidden procs previously triggered a token owner lookup per parameter, which scales badly if the lookup hits a database or auth service. The owner is now resolved lazily and at most once per params_object call.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Hiding a Hash parameter from the documentation now also hides its nested fields. Before, the parent disappeared but its children still showed up as separate query parameters pointing at something that no longer existed.
Root cause
Nested params arrive as separate
parent[child]entries whose options don't carry the parent'sdocumentation, sohidden: truewas never applied to them.The parameter-level
hidden:proc is now evaluated with the resolvedtoken_owner(looked up at most once per route, and only when a proc needs it), the same way route visibility is, sohidden: ->(user) { ... }no longer raises whentoken_owneris configured. As for route-level procs, a configuredtoken_ownermethod that does not exist now raisesTokenOwnerNotFoundfor parameter-level procs too.Drawbacks
The match is by name prefix (
parent[), so a hiddenfiltersalso hides any param literally namedfilters[...], which is the set Grape produces for its children. Siblings such asfilters_extraare unaffected. It also relies on parsers merging into the accumulator rather than removing keys from it.Rejected alternatives
Resolving each child's parent through
route.paramswould need to be repeated in every parser. Filtering once inparams_objectcovers every parser.Closes #1015