Rails, GraphQL Ruby, and a field with the JSON type in the PostgreSQL table.
There are two types of records in this field:
["One","Two","Three"][["One","Two","Three"]]This is done specially. So it is necessary.
If Rails itself displays this data as it should, then gem GraphQL inside itself works correctly only with the first view.
The second view is displayed like this:
"json_field": [
"[\"One\", \"Two\", \"Three\"]"
]
Responsible for displaying this code:
field :json_field, types[types.String]
I understand why the second option seems to grant that way, but I can not figure out how to fix it.
Help with this, please.
The two formats may be specified like this:
field :json_field, types[types.String]
# ["One", "Two", "Three"]
# OR:
field :json_field, types[types[types.String]]
# [["One", "Two", "Three"]]
but there is no way to specify them _together_. Here are some options I can think of:
Make _two_ fields, one for each format
field :shallow_strings, types[types.String] do
resolve ->(obj, args, ctx) {
if obj.json_field.first.is_a?(String)
obj.json_field
else
nil
end
}
end
field :deep_strings, types[types[types.String]] do
resolve ->(obj, args, ctx) {
if obj.json_field.first.is_a?(Array)
obj.json_field
else
nil
end
}
end
Then in graphql:
my_object {
deep_strings
shallow_strings
}
Then merge them in the view code
Use an intermediary object type + union
ShallowStrings = GraphQL::ObjectType.new
name "ShallowStrings"
field :values, types[types.String]
end
DeepStrings = GraphQL::ObjectType.define do
name "DeepStrings"
field :values, types[types[types.String]]
end
StringList = GraphQL::UnionType.define do
name "StringList"
possible_types [DeepStrings, ShallowStrings]
end
# ...
field :json_field, StringList
Then in GraphQL:
json_field {
... on ShallowStrings { values }
... on DeepStrings { values }
}
This way, the resulting "values" may be of either format.
Unions can only be created of object types.
How do those sound?
@rmosolgo Your example from the first point helped me. Thank you.
The second point I did not understand. I copied your code, but in the end I get this error:
schema contains Interfaces or Unions, so you must define a 'resolve_type -> (obj, ctx) { ... }' function (NotImplementedError)
Because of this error the project falls.
Most likely the matter is that I incorrectly pass json_field in the query.
Sorry, that error popped up because you need to define resolve_type in your schema:
http://graphql-ruby.org/types/abstract_types.html#type-resolution
I hope that helped! Feel free to reopen with more details if you're still stuck.
thank you for being so helpful @rmosolgo !
Most helpful comment
The two formats may be specified like this:
but there is no way to specify them _together_. Here are some options I can think of:
Make _two_ fields, one for each format
Then in graphql:
Then merge them in the view code
Use an intermediary object type + union
Then in GraphQL:
This way, the resulting
"values"may be of either format.Unions can only be created of object types.
How do those sound?