Skip to content

Commit 942c360

Browse files
authored
feat: filtering one-to-many relations (#73)
1 parent 180fc0e commit 942c360

File tree

5 files changed

+776
-28
lines changed

5 files changed

+776
-28
lines changed

README.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,43 @@ query {
318318

319319
<summary>Relations: Root-level, one-to-many</summary>
320320

321-
Not supported yet. [#26](https://github.com/graphile-contrib/postgraphile-plugin-connection-filter/issues/26#issuecomment-424810349)
321+
> Requires `connectionFilterRelations: true`
322+
323+
One-to-many relation fields require the filter criteria to be nested under `every`, `some`, or `none`.
324+
325+
```graphql
326+
query {
327+
allPeople(filter: {
328+
postsByAuthorId: {
329+
some: {
330+
status: { equalTo: PUBLISHED }
331+
}
332+
}
333+
}) {
334+
nodes {
335+
id
336+
createdAt
337+
}
338+
}
339+
}
340+
```
341+
342+
There is also an `exist` Boolean field for evaluating whether any related objects exist.
343+
344+
```graphql
345+
query {
346+
allPeople(filter: {
347+
postsByAuthorId: {
348+
exist: true
349+
}
350+
}) {
351+
nodes {
352+
id
353+
createdAt
354+
}
355+
}
356+
}
357+
```
322358

323359
</details>
324360

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,64 @@
11
query {
2-
parent_name_equalTo_parent2: allFilterables(filter: {parentByParentId: {name: {equalTo: "parent2"}}}) { ...stringConnection }
3-
forward_name_equalTo_forward2: allFilterables(filter: {forwardByForwardId: {name: {equalTo: "forward2"}}}) { ...stringConnection }
2+
backwardCompound_name_equalTo_backwardCompound12: allFilterables(filter: {backwardCompoundByBackwardCompound1AndBackwardCompound2: {name: {equalTo: "backwardCompound12"}}}) { ...stringConnection }
43
backward_name_equalTo_backward2: allFilterables(filter: {backwardByFilterableId: {name: {equalTo: "backward2"}}}) { ...stringConnection }
5-
#child_name_equalTo_child2: allFilterables(filter: {childrenByFilterableId: {name: {equalTo: "child2"}}}) { ...stringConnection }
4+
children_every_name_equalTo_child2: allFilterables(filter: {childrenByFilterableId: {every: {name: {equalTo: "child2"}}}}) { ...childrenConnection }
5+
children_every_name_startsWith_c: allFilterables(filter: {childrenByFilterableId: {every: {name: {startsWith: "c"}}}}) { ...childrenConnection }
6+
children_every_name_startsWith_c_and_exist_true: allFilterables(filter: {childrenByFilterableId: {every: {name: {startsWith: "c"}}, exist: true}}) { ...childrenConnection }
7+
children_every_name_startsWith_c_and_exist_false: allFilterables(filter: {childrenByFilterableId: {every: {name: {startsWith: "c"}}, exist: false}}) { ...childrenConnection }
8+
children_exist_true: allFilterables(filter: {childrenByFilterableId: {exist: true}}) { ...childrenConnection }
9+
children_exist_false: allFilterables(filter: {childrenByFilterableId: {exist: false}}) { ...childrenConnection }
10+
children_some_name_equalTo_child2: allFilterables(filter: {childrenByFilterableId: {some: {name: {equalTo: "child2"}}}}) { ...childrenConnection }
11+
children_some_name_startsWith_c: allFilterables(filter: {childrenByFilterableId: {some: {name: {startsWith: "c"}}}}) { ...childrenConnection }
12+
children_some_name_startsWith_c_and_exist_true: allFilterables(filter: {childrenByFilterableId: {some: {name: {startsWith: "c"}}, exist: true}}) { ...childrenConnection }
13+
children_some_name_startsWith_c_and_exist_false: allFilterables(filter: {childrenByFilterableId: {some: {name: {startsWith: "c"}}, exist: false}}) { ...childrenConnection }
14+
children_none_name_equalTo_child2: allFilterables(filter: {childrenByFilterableId: {none: {name: {equalTo: "child2"}}}}) { ...childrenConnection }
15+
children_none_name_startsWith_c: allFilterables(filter: {childrenByFilterableId: {none: {name: {startsWith: "c"}}}}) { ...childrenConnection }
16+
children_none_name_startsWith_c_and_exist_true: allFilterables(filter: {childrenByFilterableId: {none: {name: {startsWith: "c"}}, exist: true}}) { ...childrenConnection }
17+
children_none_name_startsWith_c_and_exist_false: allFilterables(filter: {childrenByFilterableId: {none: {name: {startsWith: "c"}}, exist: false}}) { ...childrenConnection }
618
forwardCompound_name_equalTo_forwardCompound12: allFilterables(filter: {forwardCompoundByForwardCompound1AndForwardCompound2: {name: {equalTo: "forwardCompound12"}}}) { ...stringConnection }
7-
backwardCompound_name_equalTo_backwardCompound12: allFilterables(filter: {backwardCompoundByBackwardCompound1AndBackwardCompound2: {name: {equalTo: "backwardCompound12"}}}) { ...stringConnection }
19+
forward_name_equalTo_forward2: allFilterables(filter: {forwardByForwardId: {name: {equalTo: "forward2"}}}) { ...stringConnection }
20+
parent_name_equalTo_parent2: allFilterables(filter: {parentByParentId: {name: {equalTo: "parent2"}}}) { ...stringConnection }
21+
# the following should all fail due to null and empty object checks:
22+
x_backward_name_equalTo_null: allFilterables(filter: {backwardByFilterableId: {name: {equalTo: null}}}) { ...stringConnection }
23+
x_backward_name_null: allFilterables(filter: {backwardByFilterableId: {name: null}}) { ...stringConnection }
24+
x_backward_name_empty: allFilterables(filter: {backwardByFilterableId: {name: {}}}) { ...stringConnection }
25+
x_backward_null: allFilterables(filter: {backwardByFilterableId: null}) { ...stringConnection }
26+
x_backward_empty: allFilterables(filter: {backwardByFilterableId: {}}) { ...stringConnection }
27+
x_children_every_name_equalTo_null: allFilterables(filter: {childrenByFilterableId: {every: {name: {equalTo: null}}}}) { ...childrenConnection }
28+
x_children_every_name_null: allFilterables(filter: {childrenByFilterableId: {every: {name: null}}}) { ...childrenConnection }
29+
x_children_every_name_empty: allFilterables(filter: {childrenByFilterableId: {every: {name: {}}}}) { ...childrenConnection }
30+
x_children_every_null: allFilterables(filter: {childrenByFilterableId: {every: null}}) { ...childrenConnection }
31+
x_children_every_empty: allFilterables(filter: {childrenByFilterableId: {every: {}}}) { ...childrenConnection }
32+
x_children_null: allFilterables(filter: {childrenByFilterableId: null}) { ...childrenConnection }
33+
x_children_empty: allFilterables(filter: {childrenByFilterableId: {}}) { ...childrenConnection }
34+
x_children_exist_null: allFilterables(filter: {childrenByFilterableId: {exist: null}}) { ...childrenConnection }
35+
x_forward_name_equalTo_null: allFilterables(filter: {forwardByForwardId: {name: {equalTo: null}}}) { ...stringConnection }
36+
x_forward_name_null: allFilterables(filter: {forwardByForwardId: {name: null}}) { ...stringConnection }
37+
x_forward_name_empty: allFilterables(filter: {forwardByForwardId: {name: {}}}) { ...stringConnection }
38+
x_forward_null: allFilterables(filter: {forwardByForwardId: null}) { ...stringConnection }
39+
x_forward_empty: allFilterables(filter: {forwardByForwardId: {}}) { ...stringConnection }
40+
x_parent_name_equalTo_null: allFilterables(filter: {parentByParentId: {name: {equalTo: null}}}) { ...stringConnection }
41+
x_parent_name_null: allFilterables(filter: {parentByParentId: {name: null}}) { ...stringConnection }
42+
x_parent_name_empty: allFilterables(filter: {parentByParentId: {name: {}}}) { ...stringConnection }
43+
x_parent_null: allFilterables(filter: {parentByParentId: null}) { ...stringConnection }
44+
x_parent_empty: allFilterables(filter: {parentByParentId: {}}) { ...stringConnection }
845
}
946

1047
fragment stringConnection on FilterablesConnection {
1148
nodes {
1249
id
1350
string
1451
}
52+
}
53+
54+
fragment childrenConnection on FilterablesConnection {
55+
nodes {
56+
id
57+
childrenByFilterableId {
58+
nodes {
59+
id
60+
name
61+
}
62+
}
63+
}
1564
}

0 commit comments

Comments
 (0)