-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Handle json array #2538
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
Handle json array #2538
Conversation
|
@ericproulx take a look? |
|
@mohammednasser-32 Thank you! Run |
|
@dblock Fixed 🙏 |
I'll take a look |
|
@mohammednasser-32 there's still an issue with the returned message it 'fails' do
params = {
array: [
{
a: 'a',
json: { b: 'b' }
},
{
a: 'a'
},
{
a: 'a',
json: { b: 'b' }
}
]
}
post '/nested_array', params.to_json, 'CONTENT_TYPE' => 'application/json'
expect(last_response.status).to eq(400)
expect(last_response.body).to eq('array[1][json] is missing, array[1][json][b] is missing')
end^ this test will fail. |
|
@ericproulx ah I see, the |
Yeah I know, It's a tough one. |
|
@mohammednasser-32 I'm not sure your solution works. I've simplified the issue regarding params with a Both endpoints Sending the following payload Here's are the specs context 'array without given' do
before do
subject.params do
requires :array, type: Array do
requires :a, type: Integer
requires :b, type: Integer
end
end
subject.post '/array_without_given'
end
it 'fails' do
params = {
array: [
{
a: 1,
b: 2
},
{
a: 3
},
{
a: 5
}
]
}
post '/array_without_given', params.to_json, 'CONTENT_TYPE' => 'application/json'
expect(last_response.body).to eq('array[1][b] is missing, array[2][b] is missing')
expect(last_response.status).to eq(400)
end
end
context 'array with given' do
before do
subject.params do
requires :array, type: Array do
requires :a, type: Integer
given a: ->(v) { v.odd? } do
requires :b, type: Integer
end
end
end
subject.post '/array_with_given'
end
it 'fails' do
params = {
array: [
{
a: 1,
b: 2
},
{
a: 3
},
{
a: 5
}
]
}
post '/array_with_given', params.to_json, 'CONTENT_TYPE' => 'application/json'
expect(last_response.body).to eq('array[1][b] is missing, array[2][b] is missing')
expect(last_response.status).to eq(400)
end
end |
|
@ericproulx Indeed the solution returns the correct status code but not the proper indexing, alright feel free to close the PR then..thanks for checking! |
I think I found a solution. |
|
@mohammednasser-32 could you add the tests from this comment in your branch and simply switch the |
|
@ericproulx Yes that was it! working perfectly now..thank you! pushed here |
| return params.any? { |param| meets_dependency?(param, request_params) } if params.is_a?(Array) | ||
|
|
||
| if params.is_a?(Array) | ||
| @params_meeting_dependency = params.filter { |param| meets_dependency?(param, request_params) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is memoized, shouldn't it be
| @params_meeting_dependency = params.filter { |param| meets_dependency?(param, request_params) } | |
| @params_meeting_dependency ||= params.filter { |param| meets_dependency?(param, request_params) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not really memoized, @params_meeting_dependency is initiated as an empty array and we can not memoize it because:
[] || [1,2,3] # gives [] because it is a true valueso we will not be able to change the value, I guess we don't need to memoize it anyways we only set the value once and read it with attr_reader, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so. Let’s get rid of the unneeded memorization?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but I think it is already not memorized, you mean this line right?
@params_meeting_dependency = params.filter { |param| meets_dependency?(param, request_params) }I am already using = here, so which memorization you mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind, this is fine. I see we need @params_meeting_dependency later. I dislike that we have a @ in here but it can be called multiple times.
|
@ericproulx good with you? merge? |
|
@mohammednasser-32 could you add the test in from that comment. It all started from that and I just want to make sure it passes |
|
@ericproulx done, it needed one extra small fix to handle json array within json array |
|
@mohammednasser-32 just missing a changelog entry and we're good to go. |
|
@ericproulx done 🙏 |
|
@dblock sounds good to me. |
Fix #2526
There is an issue in handling json arrays,
The problem is here we mark a Scope with type Array as meeting dependency if at least 1 element meets the dependency,
And therefore in the next iteration (json items),
@dependant_onis nil,@parentmeets dependency, and so we validate all json items, even the ones that should be skipped since they are not meeting the dependencySo I added
@params_meeting_dependencyparam (name might be changed) which filters only the json items that should be validated so we can skip the rest