Skip to content

Hoist using: / except: to explicit kwargs on requires / optional#2746

Open
ericproulx wants to merge 1 commit into
masterfrom
refactor/params-dsl-using-except-kwargs
Open

Hoist using: / except: to explicit kwargs on requires / optional#2746
ericproulx wants to merge 1 commit into
masterfrom
refactor/params-dsl-using-except-kwargs

Conversation

@ericproulx
Copy link
Copy Markdown
Contributor

Summary

Grape::DSL::Parameters#requires and #optional both treat :using (and the :except it pairs with) as a method-local early-return signal — when :using is set, the method returns through require_required_and_optional_fields / require_optional_fields and the keys never flow into validate_attributes or the validator/scope machinery.

Promote them out of the **opts Hash into explicit kwargs:

def requires(*attrs, using: nil, except: nil, **opts, &block)
def optional(*attrs, using: nil, except: nil, **opts, &block)

The signature now self-documents the using/except contract instead of burying it in opts; the if using guard drops one Hash lookup; and the opts Hash that flows into validate_attributes is "validator-bound kwargs only" — easier to reason about what propagates downstream.

Backward compatibility

Fully back-compat: Ruby kwarg matching captures using: / except: before the **opts splat, so existing call sites (requires :all, using: docs, optional :all, except: %i[…], using: docs, etc.) keep working unchanged.

The unrelated :except_values validator option (consumed by Grape::Validations::ValidationsSpec) is a different key and is unaffected.

Test plan

  • bundle exec rspec — 2313 examples, 0 failures
  • bundle exec rubocop lib/grape/dsl/parameters.rb — clean
  • CI green

Matches the recent kwargs-hoisting pattern in #2723 (desc) and #2728 (auth / http_basic / http_digest).

🤖 Generated with Claude Code

`Grape::DSL::Parameters#requires` and `#optional` both treat `:using`
(and the `:except` it pairs with) as a method-local early-return signal:
when `:using` is set, the method returns through
`require_required_and_optional_fields` / `require_optional_fields` and
the keys never flow into `validate_attributes` or the validator/scope
machinery.

Promote them out of the `**opts` Hash into explicit kwargs:

  def requires(*attrs, using: nil, except: nil, **opts, &block)
  def optional(*attrs, using: nil, except: nil, **opts, &block)

The signature now self-documents the using/except contract instead of
burying it in opts, the `if using` guard drops one Hash lookup, and the
`opts` Hash that flows into `validate_attributes` is "validator-bound
kwargs only" — easier to reason about what propagates downstream.

Fully back-compat: Ruby kwarg matching captures `using:` / `except:`
before the `**opts` splat, so existing call sites (`requires :all,
using: docs`, `optional :all, except: %i[…], using: docs`, etc.) keep
working unchanged. The unrelated `:except_values` validator option
(consumed by `Grape::Validations::ValidationsSpec`) is a different key
and is unaffected.

Matches the recent kwargs-hoisting pattern in #2723 (`desc`) and #2728
(`auth` / `http_basic` / `http_digest`).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ericproulx ericproulx force-pushed the refactor/params-dsl-using-except-kwargs branch from 4343f71 to cbf759f Compare May 24, 2026 19:51
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 24, 2026

Danger Report

No issues found.

View run

@ericproulx ericproulx requested a review from dblock May 24, 2026 20:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants