Skip to content

Ensure complete declared params structure is present - #2103

Merged
dblock merged 2 commits into
ruby-grape:masterfrom
tlconnor:deepDeclared
Sep 30, 2020
Merged

Ensure complete declared params structure is present#2103
dblock merged 2 commits into
ruby-grape:masterfrom
tlconnor:deepDeclared

Conversation

@tlconnor

Copy link
Copy Markdown

Back in April 2020 a fix was merged that ensured that missing Hash / Array params would be initialized as [] / {} during declared(params, include_missing: true).

#2043

This fix introduced a bug that would result in deeply nested param structures being replaced with an empty Hash.
#2101

This PR fixes the issue by ensuring that missing hashes are only initialized as {} if they don't have any declared nested params.

Fixes #2101

@dblock dblock left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is great. Thank you.

Let's beef up the specs a little bit: make one without deep nesting, make a separate spec for deep nested hashes, deep nested arrays, multiple levels of deep nesting.

And let's go an extra mile in README to explain these behaviors?

UPGRADING needs a paragraph, too.

@tlconnor

Copy link
Copy Markdown
Author

@dblock I have improved the specs and updated the README / CHANGELOG / and UPGRADING guide.

It is not clear to me what we should do with missing Set params. Do you think a missing Set / Set[Anything] should be resolved as Set.new, or do you think they should remain as nil?

@dblock dblock left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This LGTM with minor comments for UPGRADING.

For Set, I think it should be Set.new because [] and {} are just shortcuts for Array.new and Hash.new.

2.6.6 :001 > Hash.new
 => {} 
2.6.6 :002 > {}.class
 => Hash 
2.6.6 :003 > Hash.new == {}
 => true 
2.6.6 :004 > Array.new
 => [] 
2.6.6 :005 > [].class
 => Array 
2.6.6 :006 > Array.new == []
 => true 

Comment thread UPGRADING.md Outdated

### Upgrading to >= 1.4.1

Previous to 1.3.3, the `declared` helper would always return the complete params structure if `include_missing=true` was set. In 1.3.3 the behavior was changed, so a missing Hash with or without nested parameters would always resolve as `{}`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Previous -> prior

Comment thread UPGRADING.md Outdated
* Hash params with childern will resolve as a hash with keys for each declared child.
* Hash params with no children will resolve as `{}`.
* Array params will resolve as `[]`.
* All other params will resolve as `null`.

@dblock dblock Sep 18, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

resolve "to", not "as" I think is more correct

Add a simple before/after example.

Add a link to the PR, For more information see [#2103](https://github.com/ruby-grape/grape/pull/2103).. We've been forgetting those, would be nice to re-add where missing below.

@dblock

dblock commented Sep 18, 2020

Copy link
Copy Markdown
Member

If you don't mind feeding my OCD, squash your last two commits (amend the second one that makes the actual code change with the CHANGELOG, etc. update), and keep the move of the spec separate, so we can continue seeing the diff in the specs. NBD otherwise.

@tlconnor

Copy link
Copy Markdown
Author

@dblock all comments have now been addressed. I have also added support for Set, and have included test cases for Array[Something] and Set[Something].

@dblock dblock left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm good with this with a 🍏 build and a 1.5 version bump.

Comment thread UPGRADING.md Outdated

### Upgrading to >= 1.4.1

Prior to 1.3.3, the `declared` helper would always return the complete params structure if `include_missing=true` was set. In 1.3.3 the behavior was changed, so a missing Hash with or without nested parameters would always resolve to `{}`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

was changed -> a regression was introduced that ...

Comment thread UPGRADING.md Outdated

Prior to 1.3.3, the `declared` helper would always return the complete params structure if `include_missing=true` was set. In 1.3.3 the behavior was changed, so a missing Hash with or without nested parameters would always resolve to `{}`.

In 1.4.1 this behavior is reverted, so the whole params structure will always be available via `declared`, regardless of whether any params are passed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let's make this 1.5, and please bump the version in version.rb.

@dblock

dblock commented Sep 29, 2020

Copy link
Copy Markdown
Member

Change other references to 1.4.1 (in CHANGELOG, etc.) to 1.5.

if type == 'Hash' && !has_children
{}
elsif should_be_empty_array?(passed_children_params, params_nested_path)
elsif type == 'Array' || type&.start_with?('[')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This seems iffy but I'll let it slide. I wish we were comparing a non-String type...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I agree, it is a bit messy. It was also pre-existing, so not entirely my fault 😄

@tlconnor

Copy link
Copy Markdown
Author

Change other references to 1.4.1 (in CHANGELOG, etc.) to 1.5.

Not sure why I missed those. Now fixed.

@dblock
dblock merged commit 7e43215 into ruby-grape:master Sep 30, 2020
@dblock

dblock commented Sep 30, 2020

Copy link
Copy Markdown
Member

Merged, thanks for your excellent work here, @tlconnor! You might want to email the mailing list asking people to test this out before we release v. next.

@tlconnor

tlconnor commented Oct 1, 2020

Copy link
Copy Markdown
Author

@dblock please hold off from releasing the new version, through testing against my app I believe I have found a newly introduced bug. I will work on a fix ASAP.

stanhu added a commit to stanhu/grape that referenced this pull request Oct 9, 2020
Prior to Grape v1.5.0 and ruby-grape#2103, the following
would return `nil`:

```
params do
  optional :status_code, types: [Integer, String]
end
get '/' do
  declared_params
end
```

However, now it turns an empty `Array`.

We restore the previous behavior by not returning an empty `Array` if multiple
types are used.

Closes ruby-grape#2115
stanhu added a commit to stanhu/grape that referenced this pull request Oct 9, 2020
Prior to Grape v1.5.0 and ruby-grape#2103, the following
would return `nil`:

```
params do
  optional :status_code, types: [Integer, String]
end
get '/' do
  declared_params
end
```

However, now it turns an empty `Array`.

We restore the previous behavior by not returning an empty `Array` if multiple
types are used.

Closes ruby-grape#2115
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.

Breaking change for nested params in declared in Grape 1.3.3

2 participants