Skip to content

Commit

Permalink
Allow update mutations to pass null for optional relations (#1002)
Browse files Browse the repository at this point in the history
This makes it possible to reset an optional relation with an update mutation:

```graphql
mutation resetEvent {
  updateNotification(id: 1, data: {title: "N1-updated", event: null}) {
    id
    event
  }
}
```
  • Loading branch information
ramnivas committed Jan 17, 2024
1 parent 93b58d2 commit 19971f0
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,22 @@ fn compute_update_columns<'a>(
let self_column = self_column_id.get_column(&subsystem.database);
let foreign_type_pk_field_name =
&foreign_pk_field_id.resolve(&subsystem.entity_types).name;
get_argument_field(argument, &field.name).map(|argument_value| {
match get_argument_field(argument_value, foreign_type_pk_field_name) {
Some(foreign_type_pk_arg) => {
let value_column =
cast::literal_column(foreign_type_pk_arg, self_column);
(self_column_id, value_column.unwrap())

match get_argument_field(argument, &field.name) {
Some(Val::Null) => Some((self_column_id, Column::Null)), // `{..., foreign_field: null}` means set the column to null
Some(argument_value) => {
// `{..., foreign_field: { id: 1 }}` means set the column to the id of the nested object
match get_argument_field(argument_value, foreign_type_pk_field_name) {
Some(foreign_type_pk_arg) => {
let value_column =
cast::literal_column(foreign_type_pk_arg, self_column);
Some((self_column_id, value_column.unwrap()))
}
None => unreachable!("Expected pk argument"), // Validation should have caught this
}
None => unreachable!("Expected pk argument"), // Validation should have caught this
}
})
None => None,
}
}
PostgresRelation::OneToMany { .. } => None,
})
Expand Down
18 changes: 18 additions & 0 deletions integration-tests/optional-relation/src/index.exo
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Notification has an optional event
@postgres
module NotificationDatabase {
@access(true)
type Notification {
@pk id: Int = autoIncrement()
title: String
description: String
event: Event?
}

@access(true)
type Event {
@pk id: Int = autoIncrement()
title: String
notifications: Set<Notification>?
}
}
24 changes: 24 additions & 0 deletions integration-tests/optional-relation/tests/init.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
stages:
- operation: |
mutation {
e1: createEvent(data: {title: "E1"}) {
id @bind(name: "e1Id")
}
e2: createEvent(data: {title: "E2"}) {
id @bind(name: "e2Id")
}
}
- operation: |
mutation($e1Id: Int!, $e2Id: Int!) {
n1: createNotification(data: {title: "N1", description: "N1-desc", event: {id: $e1Id}}) {
id @bind(name: "n1id")
}
n2: createNotification(data: {title: "N2", description: "N2-desc", event: {id: $e2Id}}) {
id @bind(name: "n2id")
}
}
variable: |
{
"e1Id": $.e1Id,
"e2Id": $.e2Id
}
52 changes: 52 additions & 0 deletions integration-tests/optional-relation/tests/reset-relation.exotest
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
stages:
- operation: |
mutation resetEvent($eId: Int!) {
updateNotification(id: $eId, data: {title: "N1-updated", event: null}) {
id
event
}
}
variable: |
{
"eId": $.e1Id,
}
response: |
{
"data": {
"updateNotification": {
"id": 1,
"event": null
}
}
}
- operation: |
query {
notifications @unordered {
id
title
event {
id
title
}
}
}
response: |
{
"data": {
"notifications": [
{
"id": $.n1id,
"title": "N1-updated",
"event": null
},
{
"id": $.n2id,
"title": "N2",
"event": {
"id": $.e2Id,
"title": "E2"
}
}
]
}
}

0 comments on commit 19971f0

Please sign in to comment.