Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid coercing parameter with multiple types to an empty Array #2019

Merged

Conversation

stanhu
Copy link
Contributor

@stanhu stanhu commented Mar 17, 2020

If an optional parameter has multiple types (e.g. [File, String]) and a
nil parameter is passed, Grape would previously coerce the value to an
empty Array. This can break certain APIs that treat nil values
differently from an empty Array.

To fix this, we refactor the nil handling into a coerce_nil method and
remove the special case check for handling an Array of types.

Closes #2018

@stanhu stanhu force-pushed the sh-respect-nil-values-multiple-types branch 2 times, most recently from af12335 to 10b15fe Compare March 17, 2020 05:26
return Set.new if type == Set
return {} if type == Hash
return val if type.is_a?(Array)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this type.is_a?(Array) check. I assume that passing a nil value to a parameter with multiple types might lead to ambiguity?

Copy link
Contributor

@ericproulx ericproulx Apr 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, it was necessary

    it 'handles default value to array' do
      subject.params do
        optional :a, type: Array[Integer], default: []
      end
      subject.put('/test') { declared(params).to_json }
      put '/test', { a: nil }
      expect(last_response.status).to eq(200)
      expect(last_response.body).to eq('{"a":[]}')
    end

That test fails because type != array but it's type.is_a?(Array)
I'll make a PR to fix it

@stanhu stanhu force-pushed the sh-respect-nil-values-multiple-types branch from 10b15fe to d38b594 Compare March 17, 2020 05:37
CHANGELOG.md Outdated Show resolved Hide resolved
@dblock
Copy link
Member

dblock commented Mar 17, 2020

Looks like a bug, thanks for the fix! Move the changelog entry and I'll merge.

@stanhu stanhu force-pushed the sh-respect-nil-values-multiple-types branch from d38b594 to 43fd676 Compare March 17, 2020 13:33
@stanhu stanhu force-pushed the sh-respect-nil-values-multiple-types branch from 109d1a5 to 31d9ff0 Compare March 17, 2020 15:01
@dblock
Copy link
Member

dblock commented Mar 17, 2020

See rubocop offense, I'll merge on green.

return [] if type == Array
return Set.new if type == Set
return {} if type == Hash
return val
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just val

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a good place for a case

case type
when Array
when ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That doesn't actually work in this case because we need to distinguish between type.is_a?(Array) and type == Array (https://stackoverflow.com/questions/3908380/ruby-class-types-and-case-statements).

@stanhu stanhu force-pushed the sh-respect-nil-values-multiple-types branch from 31d9ff0 to d0e8009 Compare March 17, 2020 15:58
If an optional parameter has multiple types (e.g. [File, String]) and a
nil parameter is passed, Grape would previously coerce the value to an
empty Array. This can break certain APIs that treat nil values
differently from an empty Array.

To fix this, we refactor the nil handling into a `coerce_nil` method and
remove the special case check for handling an Array of types.

Closes ruby-grape#2018
@stanhu stanhu force-pushed the sh-respect-nil-values-multiple-types branch from d0e8009 to 633d7cf Compare March 17, 2020 16:34
@dblock dblock merged commit dcd50d3 into ruby-grape:master Mar 17, 2020
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.

Optional values with multiple types get coerced to an empty Array
3 participants