diff --git a/CHANGELOG.md b/CHANGELOG.md index 5054c1dac9..eb49886960 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * [#2083](https://github.com/ruby-grape/grape/pull/2083): Set `Cache-Control` header only for streamed responses - [@stanhu](https://github.com/stanhu). * [#2092](https://github.com/ruby-grape/grape/pull/2092): Correct an example params in Include Missing doc - [@huyvohcmc](https://github.com/huyvohcmc). * [#2091](https://github.com/ruby-grape/grape/pull/2091): Fix ruby 2.7 keyword deprecations - [@dim](https://github.com/dim). +* [#2097](https://github.com/ruby-grape/grape/pull/2097): Skip to set default value unless `meets_dependency?` - [@wanabe](https://github.com/wanabe). ### 1.4.0 (2020/07/10) diff --git a/lib/grape/validations/validators/default.rb b/lib/grape/validations/validators/default.rb index 79d6951f37..dbf754ed84 100644 --- a/lib/grape/validations/validators/default.rb +++ b/lib/grape/validations/validators/default.rb @@ -21,6 +21,7 @@ def validate_param!(attr_name, params) def validate!(params) attrs = SingleAttributeIterator.new(self, @scope, params) attrs.each do |resource_params, attr_name| + next unless @scope.meets_dependency?(resource_params, params) validate_param!(attr_name, resource_params) if resource_params.is_a?(Hash) && resource_params[attr_name].nil? end end diff --git a/spec/grape/validations/validators/default_spec.rb b/spec/grape/validations/validators/default_spec.rb index 10220eb58e..ae16445eb6 100644 --- a/spec/grape/validations/validators/default_spec.rb +++ b/spec/grape/validations/validators/default_spec.rb @@ -419,4 +419,53 @@ def app end end end + + context 'array with default values and given conditions' do + subject do + Class.new(Grape::API) do + default_format :json + end + end + + def app + subject + end + + it 'applies the default values only if the conditions are met' do + subject.params do + requires :ary, type: Array do + requires :has_value, type: Grape::API::Boolean + given has_value: ->(has_value) { has_value } do + optional :type, type: String, values: %w[str int], default: 'str' + given type: ->(type) { type == 'str' } do + optional :str, type: String, default: 'a' + end + given type: ->(type) { type == 'int' } do + optional :int, type: Integer, default: 1 + end + end + end + end + subject.post('/nested_given_and_default') { declared(self.params) } + + params = { + ary: [ + { has_value: false }, + { has_value: true, type: 'int', int: 123 }, + { has_value: true, type: 'str', str: 'b' } + ] + } + expected = { + 'ary' => [ + { 'has_value' => false, 'type' => nil, 'int' => nil, 'str' => nil }, + { 'has_value' => true, 'type' => 'int', 'int' => 123, 'str' => nil }, + { 'has_value' => true, 'type' => 'str', 'int' => nil, 'str' => 'b' } + ] + } + + post '/nested_given_and_default', params + expect(last_response.status).to eq(201) + expect(JSON.parse(last_response.body)).to eq(expected) + end + end end