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

Ensure complete declared params structure is present #2103

Merged
merged 2 commits into from Sep 30, 2020

Conversation

tlconnor
Copy link
Contributor

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

Copy link
Member

@dblock dblock left a comment

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
Contributor 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?

Copy link
Member

@dblock dblock left a comment

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 

UPGRADING.md Outdated
@@ -1,6 +1,19 @@
Upgrading Grape
===============

### 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
Member

Choose a reason for hiding this comment

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

Previous -> prior

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`.
Copy link
Member

@dblock dblock Sep 18, 2020

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
Copy link
Member

dblock commented Sep 18, 2020

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
Contributor 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].

Copy link
Member

@dblock dblock left a comment

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.

UPGRADING.md Outdated
@@ -1,6 +1,45 @@
Upgrading Grape
===============

### 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
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 ...

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
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
Copy link
Member

dblock commented Sep 29, 2020

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

{}
elsif should_be_empty_array?(passed_children_params, params_nested_path)
elsif type == 'Array' || type&.start_with?('[')
Copy link
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
Contributor 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
Contributor 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
Copy link
Member

dblock commented Sep 30, 2020

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
Copy link
Contributor Author

tlconnor commented Oct 1, 2020

@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