Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
* [#3071](https://github.com/ruby-grape/grape/pull/3071): Skip the query parse when building the params of a request with no query string - [@ericproulx](https://github.com/ericproulx).
* [#3072](https://github.com/ruby-grape/grape/pull/3072): Answer the `Accept` lists axios, jQuery and HTTPie send without negotiating them on every request - [@ericproulx](https://github.com/ericproulx).
* [#3073](https://github.com/ruby-grape/grape/pull/3073): Let a `rescue_from :all` in a namespace or mounted API outrank the enclosing scope's handlers - [@ericproulx](https://github.com/ericproulx).
* [#3075](https://github.com/ruby-grape/grape/pull/3075): Validate the params of an optional Hash scope without the attributes iterator - [@ericproulx](https://github.com/ericproulx).
* [#3076](https://github.com/ruby-grape/grape/pull/3076): Skip the query merge when building the params of a body sent without a query string - [@ericproulx](https://github.com/ericproulx).
* Your contribution here.

Expand Down
18 changes: 10 additions & 8 deletions lib/grape/validations/validators/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,17 +121,19 @@ def validate_param!(attr_name, params)
# time a validator is built. See #validate and #validate!.
def choose_validation_path(scope)
@always_validated = scope.always_validated?
@direct = @always_validated && !scope.iterates_elements?
@direct = scope.independent? && scope.array_depth.zero?
@direct_elements = scope.validated_when_given? && scope.iterates_elements? && scope.array_depth == 1
end

# #validate! on a scope that always validates and does not iterate
# elements, once its params resolved to a Hash: the root scope and the
# required Hash scopes under it, which is most validators of most
# endpoints. There the iterator hands back that Hash alone, and every
# scope on the chain is required with no dependency, so the checks
# around the attribute loop drop out. The machinery cost more than
# the validation itself.
# #validate! on a scope with no Array scope and no +given+ on its
# chain, once its params resolved to a Hash: the root scope and the
# Hash scopes under it, required or optional, which is most validators
# of most endpoints. There the iterator hands back that Hash alone,
# and no scope on the chain has a dependency to meet. An optional one
# is only passed over when its params are empty, and #validate does
# not get this far with those (see ParamsScope#should_validate?). So
# the checks around the attribute loop drop out. The machinery cost
# more than the validation itself.
def validate_attributes!(params)
array_errors = nil

Expand Down
9 changes: 5 additions & 4 deletions lib/grape/validations/validators/default_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ def validate!(params)
private

# Also #validate!'s whole job where Base#validate_attributes! applies:
# a scope that is always validated and does not iterate elements, once
# its params resolved to a Hash -- the root scope of every +params+
# block with a default in it. A scope like that depends on no other
# param, so the iterator and its dependency check have nothing to add.
# a scope with no Array scope and no +given+ on its chain, once its
# params resolved to a Hash -- the root scope of every +params+ block
# with a default in it, and the Hash scopes under it. A scope like
# that depends on no other param, so the iterator and its dependency
# check have nothing to add.
def apply_defaults(params)
@attrs.each do |attr_name|
params[attr_name] = @default_call.call(params) if params[attr_name].nil?
Expand Down
Loading