-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Wierd behavior with optional array #615
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
Conversation
@lasseebert , thanks for opened issue and spec. Your expectations are right. Recently I updated |
BTW, @lasseebert I'd like to hear your opinion about this spec ?) |
A tough one. I think it makes most sense to not use inner default values when the hash itself is not represented in the request. Consider this:
A required param inside an optional parent should only be required if the parent is present. But if the optional A more sane way would be to only consider inner params if the parent hash is represented in the request. This was just my humble oppinion. I have only worked with Grape for a couple of months, and I'm not sure if my proposals will have bad side effects. |
@lasseebert , good opinion! Honestly, I have same feelings about this problem. Thx) |
Thanks. Let me know if you need me to do anything ;) |
@lasseebert , sure :) @dblock , see comments above, what do you think. Can we revert changes provided by #538, #537 in this version? /cc @dsager |
@dm1try - I am not sure I completely understand this. Want to put up a PR and I'll read things carefully? |
Hi everyone, When I need to rely on the presence of a certain parameter, I specify a default value. And when I need a hash to have certain key-value pairs, I also specify default values. So the motivation for committing the above mentioned spec (46c2737) was the need for a hash parameter whose values are always present. The most frequent use case is a paging parameter hash:
With this code I can use Looking at the code now it seems like the handling of groups changed anyway? In version 0.6.x |
Hi @dsager Thanks for taking the time for this :) I agree that it's not abvious what would be a the desired expectation for inner default values when dealing with Hash values. My original concern was when dealing with arrays:
When nothing about The behavior now is that the array param is set to a hash, which is a little weird:
|
Hi @lasseebert,
I think both behaviours make sense in respective use cases. So I'd love to see both supported. Question is how? Maybe a default option for the group itself:
Or have an additional option to explicitly enforce default-only groups:
What do you think about this, @dm1try & @dblock? Thanks for discussing this! |
Hi @dsager I really like the idea of For parameters of |
Hi @lasseebert, |
Hi @dsager Just to make sure I understand you right: When declaring
What would |
Hey @lasseebert, |
But |
Ah sorry, i got confused. I meant that the value for |
Ok, I understand now ;) |
@lasseebert, note that I'm just user/contributor and not a collaborator, so the final word on this should come from @dm1try or @dblock ... :) |
It might be a good idea to make the parameter more descriptive, e.g. |
Oh wow, this is one is interesting. I'll start by the tail-end. Saying Here's what I would propose: optional :foo, type: Array do
optional :bar, default: "bar"
end In this example However, optional :foo, type: Array, default: [] do
optional :bar, default: "bar"
end When this parameter is not present, it defaults to Lets look at a hash: optional :foo, type: Hash, default: {} do
optional :bar, default: "bar"
end This is the same thing, it defaults to optional :foo, type: Hash, default: { bar: 'baz' } do
optional :bar, default: "bar"
end I think this would be explicit and consistent for all types. The way I think about it is "i'm checking a parameter, it's not there, apply its default and stop at that". What do you think? |
Btw, this bug describes exactly what I am thinking I think :) |
Very nice and concise, @dblock. I really like this! |
To bring back the paging example: optional :page, type: Hash, default: { number: 1, size: 10 } do
requires :number, type: Integer, desc: 'Page number'
optional :size, type: Integer, desc: 'Page size', default: 10
end While i agree that its intuitive, it will add some duplication in some situations. Alternatively optional :page, type: Hash, add_defaults_if_missing: true do
requires :number, type: Integer, desc: 'Page number', default: 1
optional :size, type: Integer, desc: 'Page size', default: 10
end would not have that issue, but |
@yaneq We should solve that problem separately. Ambiguity is certainly worse than duplication. What if: optional :page, type: Hash, default: { number: 1, size: 10 } do
requires :number, type: Integer, desc: 'Page number'
optional :size, type: Integer, desc: 'Page size',
default: -> { default[:size] } # or even just default[:size] if we can
end Otherwise I would declare |
Interesting indeed :) Assuming: optional :page, type: Hash, default: { number: 1, size: 10 } do
optional :number, type: Integer
optional :size, type: Integer
end Expecting:
{ page: { number: 2, size: 5 } }
{ page: { number: 2, size: 10 } }
{ page: { number: 1, size: 5 } }
{ page: { number: 1, size: 10 } } |
Great job, guys! Who want to help with implementation? :) |
@dm1try I have not yet implemented anything in Grape, but let me know if I can help with code review or implementation ;) |
did we agree what solution to implement yet? :) |
I can play the role of the benevolent dictator. I want the solution that I described above. No hard feelings :) |
Challenge accepted! Sorry for delay 😬 |
Bump. |
@dblock , sorry. It's a little hard to implement the solution described by you for now.
Need more time or some help/suggestions) Thanks. |
@dm1try Any suggestions of what to do with this? |
@dblock Oh, it is hard for me at the moment :) I didn't implemented the solution described above. |
Hi. First of all, thanks for a great framework.
I think I have found a bug:
If I have an optional array of hashes and one of the hash values has a default, the resulting param is weird when not provided.
Example:
When not providing
:some_array
, I would expectparams[:some_array]
to benil
, but it is{foo: "bar"}
(which is not even an array).In this pull request I have med a spec that shows this.
Are my expectations right?