Repository navigation
Add include_undefined_query_parameters config flag - #2
Closed
jbaxendale-ut wants to merge 31 commits into
Closed
jbaxendale-ut wants to merge 31 commits into
jbaxendale-ut wants to merge 31 commits into
Conversation
JavaScript uses undefined to mean “not provided,” but js-routes was treating undefined query object values the same as Rails nil. After Rails 8.1, that became more visible because nil query params serialize as bare keys, so an omitted JS value could unexpectedly produce a query param like ?foo. Adds an opt-in js-routes setting, omit_undefined_query_parameters, that makes the default serializer skip object properties whose value is undefined. Explicit null still means Rails nil and keeps the Rails-version-specific behavior, including Rails 8.1 bare-key serialization.
jbaxendale-ut
force-pushed
the
feature/omit_undefined_query_parameters
branch
from
May 27, 2026 20:38
2a00659 to
caf0537
Compare
There was a problem hiding this comment.
Pull request overview
Adds an opt-in configuration flag to the generated js-routes runtime so that the built-in query serializer can omit object properties whose value is undefined (while preserving existing Rails-nil behavior for explicit null, including Rails 8.1 bare-key serialization).
Changes:
- Introduces
omit_undefined_query_parametersconfiguration (Ruby config → JS runtimeRubyVariables→ runtimeConfiguration). - Updates the built-in default serializer to skip
undefinedobject properties when the flag is enabled. - Adds/updates specs, typings, and README documentation to cover and expose the new option.
Reviewed changes
Copilot reviewed 8 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| spec/js_routes/rails_routes_compatibility_spec.rb | Adds coverage ensuring optional path fragment handling isn’t broken when the new flag is enabled. |
| spec/js_routes/options_spec.rb | Verifies the new config is exposed via Routes.config(). |
| spec/js_routes/module_types/dts/routes.spec.d.ts | Updates DTS spec fixture to include the new configuration and Ruby variable types. |
| spec/js_routes/default_serializer_spec.rb | Adds detailed serializer behavior coverage for default vs. omit-enabled modes across Rails nil serialization variants. |
| Readme.md | Documents the new omit_undefined_query_parameters option and its interaction with Rails nil behavior and custom serializers. |
| lib/routes.ts | Adds the config field, plumbs it from RubyVariables, and updates the default serializer to omit undefined object props when enabled. |
| lib/routes.js | Compiled runtime update mirroring the TypeScript changes. |
| lib/routes.d.ts | Updates published TypeScript declarations for the new config/Ruby variable fields. |
| lib/js_routes/instance.rb | Exposes OMIT_UNDEFINED_QUERY_PARAMETERS into the generated JS variables. |
| lib/js_routes/configuration.rb | Adds the Ruby-side configuration attribute with default false. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
jbaxendale-ut
commented
May 27, 2026
| } | ||
| end | ||
|
|
||
| it "should provide this method" do |
Author
There was a problem hiding this comment.
this was duplicated on line 15
… changing the default behavior. This patch implements that.
What changed:
- omit_undefined_query_parameters is now a tri-state migration option:
- nil default: keeps legacy behavior and warns
- false: keeps legacy behavior without warning
- true: omits object keys whose value is undefined
- Existing apps remain backward compatible because the unset default still serializes undefined as Rails nil.
- New generated initializers opt into the future behavior:
c.omit_undefined_query_parameters = true
- The generated JS config now represents the unset Ruby value as null, and TypeScript/DTS types allow boolean | null.
- Tests cover the migration path:
- unset warns and preserves legacy serialization
- explicit false preserves legacy serialization without warning
- explicit true omits undefined
- generator template sets the option to true
This matches the requested “nil by default, backward compatible with warning, generator sets true” first phase.
Review asked that Ruby make the migration decision before generation and that the TypeScript runtime receive a non-nullable boolean. Emit true only for an explicit true setting and update generated DTS fixtures to match.
Review asked us to avoid migration warnings in regular tests by specifying the new config. Default evallib and the suite-wide JsRoutes config to false, then remove the per-spec workaround in options_spec.
Review asked us to avoid Rails.version stubs and rely on real Rails behavior, backed by Rails 8.1 in CI. Compare JS output to Rails to_query and add the Rails 8.1/Ruby 3.4 appraisal entry.
Review asked that the omit_undefined_query_parameters optional-path assertion live with the migration tests, not the generic Rails compatibility suite. Move that coverage and keep the migration expectations aligned with the boolean runtime config and Rails to_query serializer.
Review called the generator assertion unnecessary. The initializer template itself remains covered by generation behavior, so this only deletes the added content check.
Review asked for more migration guidance in the changelog. Expand the note to explain the warning, when to choose true, when to keep false, and that explicit null still maps to Rails nil.
…lib/routes.ts:269-273
When omit_undefined_query_parameters is enabled, an object inside an array can now serialize to an empty string if all of its properties are undefined; the
array branch still pushes that empty sub-result, so Routes.serialize({a: [{b: undefined}, {c: 1}]}) returns &a%5B%5D%5Bc%5D=1 with a leading empty
parameter. Filter empty sub-serializations in the array path the same way the object path does.
jbaxendale-ut
force-pushed
the
feature/omit_undefined_query_parameters
branch
from
May 28, 2026 18:37
bfbc90b to
2a21149
Compare
omit_undefined_query_parameters config flaginclude_undefined_query_parameters config flag
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Reviewer asked to use Ruby 4.0 for the Rails 8.1 appraisal. Update only that CI matrix entry.
Reviewer asked to pass the transitional config into route generation and inline the single-use helper. Keep evallib default explicit while allowing specs to override it.
Reviewer asked for migration guidance in the generated initializer. Add the transitional wording without changing the configured default.
Reviewer asked to use Rails to_query expectations after omitting undefined values. Update the serializer specs, add the mixed-array case, and keep array serialization aligned with Rails empty fragments.
When include_undefined_query_parameters is false, undefined object properties are omitted before serialization, but the resulting structure should still serialize like Rails to_query. Add coverage for nested undefined array elements, nested objects that become empty inside arrays, and route-helper nested query properties.
…omit_undefined_query_parameters # Conflicts: # CHANGELOG.md # lib/js_routes/instance.rb # lib/routes.d.ts # lib/routes.js # lib/routes.ts # lib/templates/initializer.rb # spec/js_routes/module_types/dts/routes.spec.d.ts
jbaxendale-ut
force-pushed
the
feature/omit_undefined_query_parameters
branch
from
June 3, 2026 18:53
2ce9376 to
c4fce45
Compare
Remove a duplicate null/undefined compatibility assertion and clarify descriptions for the default serializer examples. This keeps the omit-undefined branch focused while leaving the Rails empty-hash array behavior documented as pending.
Author
|
Fixed in railsware#346 |
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.
JavaScript uses undefined to mean “not provided” but js-routes was treating undefined query object values the same as null, which ultimately became present and nil when parsed by Rails 8.1's new parameter handling (where they came in as
?fooas opposed to previous?foo=to avoid an exploit vector)This PR adds an opt-in configuration setting,
include_undefined_query_parameters, that makes the default serializer skip object properties whose value is undefined.Explicit null still means Rails nil and keeps the Rails-version-specific behavior, including Rails 8.1 bare-key serialization.
The
nilvalue of the flag will prompt those upgrading to see a warning about choosing a deliberate behavior and leave the new behavior disabled, while the generator will default new installations tofalseFinally, updated a few version checks to use
Gem::Versionwhich are a bit safer than straight string comparisons (as I ran into issues testing from a few of these not resolving completely at the time), as well as adds Rails 8.1 and Ruby 3.4 to the CI matrix.Mirroring in the main repo: railsware#346
Need help on this PR? Tag
@codesmithwith what you need. Autofix is disabled.