graphqlhasura

How to build a many-to-many insert mutation in Hasura?


I am building my first many-to-many insert mutation in Hasura and finding it difficult. The syntax in the docs and the accompanying explanation is very difficult to follow.

I am simply trying to add a connection between a component and a module.

Here is the state of my current query.

mutation MyMutation {
  insert_component(objects: {component_module: {data: {module: {data: {id: "775c9e27-c974-4cfa-a01f-af50bd742726"}, on_conflict: {constraint: module_id_key, update_columns: id}}}}}) {
    affected_rows
    returning {
      id
      component_modules
    }
  }
}

Here is the error I get.

{
  "errors": [
    {
      "extensions": {
        "path": "$.selectionSet.insert_component.args.objects[0].component_module.data",
        "code": "constraint-violation"
      },
      "message": "Not-NULL violation. null value in column \"component_id\" violates not-null constraint"
    }
  ]
}

Thanks in advance for your help.


Solution

  • Your mutation is not working because you are inserting the id manually and when Hasura generates the query it won't have the id in the parent.

    When doing nested inserts the best is to let PostgreSQL generate the ids for you. This way you will be able to insert with either side of the relationship.

    In your example you don't really need to have the component_modules column in each table. When doing many to many inserts you can use the id of each table as the foreign key.

    For example:

    component - id - created_at - updated_at - name module - id - created_at - updated_at - name component_module - component_id - module_id

    And the mutation should be something like:

    mutation {
      insert_component(objects: {
        name:"component name",
        component_modules: {
          data: {
            module: {
              data: {
                name: "module name"
              }
            }
          }
        }
      }) {
        returning {
          id
          component_modules {
            component {
              name
            }
          }
        }
      }
    }