diff --git a/CHANGELOG.md b/CHANGELOG.md index ac36f9d3f..719265202 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ * [#2733](https://github.com/ruby-grape/grape/pull/2733): Drop the dead `active_support/core_ext/hash/reverse_merge` require; call `ActiveSupport::HashWithIndifferentAccess.new(...)` directly at call sites - [@ericproulx](https://github.com/ericproulx). * [#2734](https://github.com/ruby-grape/grape/pull/2734): Extract `options_route_enabled` from the Endpoint options Hash into a dedicated `attr_accessor` - [@ericproulx](https://github.com/ericproulx). * [#2736](https://github.com/ruby-grape/grape/pull/2736): Collapse `Endpoint#run_validators` rescue branches via `ValidationErrors` flatten; `ValidationErrors#initialize` keyword renamed `errors:` → `exceptions:` - [@ericproulx](https://github.com/ericproulx). +* [#2746](https://github.com/ruby-grape/grape/pull/2746): Hoist `using:` / `except:` from `**opts` to explicit kwargs on `DSL::Parameters#requires` and `#optional` - [@ericproulx](https://github.com/ericproulx). * [#2742](https://github.com/ruby-grape/grape/pull/2742): Prune unused requires in `lib/grape.rb`; narrow `active_support/inflector` to `core_ext/string/inflections` - [@ericproulx](https://github.com/ericproulx). * [#2741](https://github.com/ruby-grape/grape/pull/2741): Readability pass: guard clauses and small extractions across `lib/` - [@ericproulx](https://github.com/ericproulx). * [#2740](https://github.com/ruby-grape/grape/pull/2740): Lazy-allocate `@api_class` and `@point_in_time_copies` on `Grape::Util::InheritableSetting` so unused settings layers don't carry an empty Hash and empty Array each - [@ericproulx](https://github.com/ericproulx). diff --git a/lib/grape/dsl/parameters.rb b/lib/grape/dsl/parameters.rb index e298a747d..babb10d18 100644 --- a/lib/grape/dsl/parameters.rb +++ b/lib/grape/dsl/parameters.rb @@ -122,11 +122,11 @@ def use(*names, **options) # requires :name, type: String # end # end - def requires(*attrs, **opts, &block) + def requires(*attrs, using: nil, except: nil, **opts, &block) opts[:presence] = { value: true, message: opts[:message] } opts = @group.deep_merge(opts) if @group - return require_required_and_optional_fields(attrs.first, using: opts[:using], except: opts[:except]) if opts[:using] + return require_required_and_optional_fields(attrs.first, using:, except:) if using validate_attributes(attrs, **opts, &block) block ? new_scope(attrs.first, type: opts[:type], as: opts[:as], &block) : push_declared_params(attrs, as: opts[:as]) @@ -136,7 +136,7 @@ def requires(*attrs, **opts, &block) # endpoint. # @param (see #requires) # @option (see #requires) - def optional(*attrs, **opts, &block) + def optional(*attrs, using: nil, except: nil, **opts, &block) type = opts[:type] opts = @group.deep_merge(opts) if @group @@ -146,7 +146,7 @@ def optional(*attrs, **opts, &block) raise Grape::Exceptions::UnsupportedGroupType unless Grape::Validations::Types.group?(type) end - return require_optional_fields(attrs.first, using: opts[:using], except: opts[:except]) if opts[:using] + return require_optional_fields(attrs.first, using:, except:) if using validate_attributes(attrs, **opts, &block) block ? new_scope(attrs.first, type: opts[:type], as: opts[:as], optional: true, &block) : push_declared_params(attrs, as: opts[:as])