Describe the bug
A clear and concise description of what the bug is.
I am attempting to do a query on a type that contains another type as a field, it is a 1 - many relationship (Schools -> Students).
On the many side I am attempting to to only get records that have a truthy field for sick and I am hoping to get all schools no matter if they have students or not.
Versions
graphiql-rails (1.7.0)
graphql (1.11.1)
graphql_devise (0.13.4)
'rails', '~> 6.0.3', '>= 6.0.3.2'
GraphQL schema
Include relevant types and fields (in Ruby is best, in GraphQL IDL is ok).
Are you using interpreter? Any custom instrumentation, etc?
module Types
class StudentType < Types::BaseObject
field :id, ID, null: false
field :name, String, null: true
field :sick, Boolean, null: true
end
end
module Types
class SchoolType < Types::BaseObject
field :id, ID, null: false
field :rating, Integer, null: true
field :name, String, null: false
field :students, [StudentType], null: true
end
end
GraphQL query
I have tried two approaches:
query SchoolsSickStudents($sick: Boolean = true) {
schools {
id
rating
name
students @include(if: $sick) {
name
sick
}
}
}
Result doesn't error but the logic operation doesn't work:
{
"data": {
"schools": [
{
"id": "1",
"rating": 2,
"name": "School A",
"students": [
{
"name": "Joe",
"sick": true
},
{
"name": "Sally",
"sick": false
}
]
},
]
}
These approach looks like it might be more accurate:
query SchoolsSickStudents {
schools {
id
rating
name
students ( where: { sick: {_eq: true}
}) {
name
sick
}
}
}
Results:
Error: unknown argument "where" on field students of type schools
Steps to reproduce
Run the query
Expected behavior
I am attempting to do a query on a type that contains another type as a field, it is a 1 - many relationship (Schools -> Students)
Actual behavior
Getting all results back or getting an error
What specifically went wrong?
Place full backtrace here (if a Ruby exception is involved):
Click to view exception backtrace
{
"errors": [
{
"message": "Field 'students' doesn't accept argument 'where'",
"sctudents": [
{
"line": 243,
"column": 17
}
],
"path": [
"query SchoolsSickStudents",
"schools",
"students",
"where"
],
"extensions": {
"code": "argumentNotAccepted",
"name": "students",
"typeName": "Field",
"argumentName": "where"
}
}
]
}
Additional context
If we had an example of this in the documentation where we did this type of query that would be helpful.
I looked there and in other places.
Hi! If you want to filter data in your application, then you should:
For example, you could add an argument like this:
module Types
class SchoolType < Types::BaseObject
field :id, ID, null: false
field :rating, Integer, null: true
field :name, String, null: false
- field :students, [StudentType], null: true
+ field :students, [StudentType], null: true do
+ argument :is_sick, Boolean, required: false
+ end
end
end
Then, implement def students to perform filtering with the given is_sick value:
module Types
class SchoolType < Types::BaseObject
field :id, ID, null: false
field :rating, Integer, null: true
field :name, String, null: false
field :students, [StudentType], null: true do
argument :is_sick, Boolean, required: false
end
+
+ def students(is_sick: nil)
+ students = object.students
+ if !is_sick.nil?
+ students = students.where(sick: is_sick)
+ end
+ students
+ end
end
end
Then, you can query the schema like this:
query SchoolsSickStudents {
schools {
id
rating
name
students(isSick: true) {
name
sick
}
}
}
isSick: true will pass true along to is_sick in def students.
There's no built-in database filtering in GraphQL (because GraphQL is backend-agnostic). The example you found in Hasura is because Hasura is coupled to a database, so it can make assumptions about how to filter things. $include isn't a dynmaic filter; instead, it statically ignores parts of the query based on the the value of if: ....
I hope that helps!
Most helpful comment
Hi! If you want to filter data in your application, then you should:
For example, you could add an argument like this:
Then, implement
def studentsto perform filtering with the givenis_sickvalue:Then, you can query the schema like this:
isSick: truewill passtruealong tois_sickindef students.There's no built-in database filtering in GraphQL (because GraphQL is backend-agnostic). The example you found in Hasura is because Hasura is coupled to a database, so it can make assumptions about how to filter things.
$includeisn't a dynmaic filter; instead, it statically ignores parts of the query based on the the value ofif: ....I hope that helps!