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
Don't use fetch
for fields that use hash_key
#4060
Conversation
Co-authored-by: George Xu <george.xu@chime.com>
Co-authored-by: georgexu22@chime.com
Co-authored-by: George Xu <george.xu@chime.com>
Co-authored-by: georgexu22@chime.com
inner_object.fetch(@hash_key) { | ||
inner_object[@hash_key_str] | ||
} | ||
inner_object[@hash_key].nil? ? inner_object[@hash_key_str] : inner_object[@hash_key] |
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.
Actually I am worried this might not work; if the value is actually nil
this will revert to @hash_key_str
. In that case it could be fine anyways depending on the resolver - since we return hash_key_str
if the client doesn't find hash_key
.
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.
Curious what're your thoughts @rmosolgo? Personally it's a bit weird to see hash_key
not be guarded by is_a?(Hash)
-- but maybe it's meant to be used this way as noticed in previous PRs.
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.
We're also unsure how hash_key
is supposed to be used. Reference in the docs: If the underlying object is a Hash, lookup a key in that hash.
. Is this not the case anymore?
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 chose fetch
because it would return nil
if the key is present in inner_object
and the value is nil
-- I think we should retain that behavior.
How about:
inner_object[@hash_key].nil? ? inner_object[@hash_key_str] : inner_object[@hash_key] | |
inner_object.key?(@hash_key) ? inner_object[@hash_key] : inner_object[@hash_key_str] |
(it looks like .key?
is what the code used to use: https://github.com/rmosolgo/graphql-ruby/pull/4015/files#diff-53ed7db7a95b84a82815af3a920ccd962fce9469ef21ed25111fb149bc1406eaL658-L661)
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.
Sorry if I'm unclear @rmosolgo or maybe we're mis-understanding, but actually I think the problem is that we have this:
if defined?(@hash_key)
check outside of checking whether or not the underlying object is a Hash
, example code from today: link. The bug is in our code, but also I think exposes an issue here -- which is that clients can define hash_key
even if the underlying object isn't a hash and have it regress.
So even if we use .key?
I think it would break... maybe the proper fix is to actually move the @hash_key
code block back into here?
…before trying to see if `@hash_key` is defined
I tried a bunch of different options in the commit tree. Maybe it's best to defer to you 😂 |
Thinking out loud when visiting this method, it's checking class type and also method resolution. Ideally we should split it into: case inner_object
when Hash
....
else
....
end And then do the behavior -- but.... this is risky 😅, as I imagine clients may have field names that are |
Thanks Robert! Funnily enough our code was broken as we used We used |
This is a proposal to fix #4059.
The TL;DR of our issue is that
#fetch
doesn't exist on all Objects, so ifinner_obj
is not aHash
or doesn't respond to#fetch
, this can break 😖