From 8be56b29242e8c15dcd7de4e75243e24f4e4c9c3 Mon Sep 17 00:00:00 2001 From: cyphercodes Date: Wed, 5 Aug 2026 06:11:37 +0300 Subject: [PATCH] Preserve positional options for named params Fixes #2851 --- CHANGELOG.md | 1 + lib/grape/dsl/parameters.rb | 2 ++ spec/grape/dsl/parameters_spec.rb | 7 +++++++ 3 files changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13b9d75a3..e64cc00ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,7 @@ * [#2829](https://github.com/ruby-grape/grape/pull/2829): Fix a cascading route handing over only to the last route registered for the path, making a middle version (3+ mounted versions with a catch-all) answer 406 - [@ericproulx](https://github.com/ericproulx). * [#2826](https://github.com/ruby-grape/grape/pull/2826): Fix `api.version` not being set for the root route of a path-versioned API (`GET /v1`) - [@ericproulx](https://github.com/ericproulx). * [#2842](https://github.com/ruby-grape/grape/pull/2842): Warn at definition time when a `rescue_from` class is already covered by one registered earlier in the same scope, since the later handler never runs - [@ericproulx](https://github.com/ericproulx). +* [#2852](https://github.com/ruby-grape/grape/pull/2852): Preserve positional options hashes passed to named params - [@cyphercodes](https://github.com/cyphercodes). * Your contribution here. ### 3.3.5 (2026-07-30) diff --git a/lib/grape/dsl/parameters.rb b/lib/grape/dsl/parameters.rb index 001c4283e..9dd042402 100644 --- a/lib/grape/dsl/parameters.rb +++ b/lib/grape/dsl/parameters.rb @@ -54,6 +54,8 @@ def build_with(build_with) # end # end def use(*names, **options) + options = names.pop if options.empty? && names.size > 1 && names.last.is_a?(Hash) + named_params = @api.inheritable_setting.named_params || {} names.each do |name| params_block = named_params.fetch(name) do diff --git a/spec/grape/dsl/parameters_spec.rb b/spec/grape/dsl/parameters_spec.rb index f312ed962..12d4bc73d 100644 --- a/spec/grape/dsl/parameters_spec.rb +++ b/spec/grape/dsl/parameters_spec.rb @@ -63,6 +63,13 @@ def new_group_scope(group) subject.use :params_group, **options end + it 'extracts a positional options hash from named params' do + subject.api = Class.new { include Grape::DSL::Settings }.new + subject.api.inheritable_setting.add_named_params(named_params) + expect(subject).to receive(:instance_exec).with(options).and_yield + subject.use :params_group, options + end + it 'raises error when non-existent named param is called' do subject.api = Class.new { include Grape::DSL::Settings }.new expect { subject.use :params_group }.to raise_error('Params :params_group not found!')