0

Hello i am making recipe app and at this point i have to create editing functionality by getting update mutation from hasura.But i have issues trying to create this mutation.Because there are two tables related to each other, one of them is recipes and other related by id is ingredient which is a array of objects .I need to populate existing form with a dynamic ingredient field with existing recipe data and then to be able to edit that data .At first i thought i will be able to create something similar to what i did with insert mutation but inserting and updating have diferent properties and im abit lost here.

here is how i wrote my insertion mutation which is working fine

mutation insertRecipe(
  $title: String!
  $image: String!
  $description: String!
  $Date: date!
  $ingredient_relation: [ingredient_insert_input!]!
) {
  insert_recipes(
    objects: {
      title: $title
      image: $image
      description: $description
      Date: $Date
      ingredient_relation: { data: $ingredient_relation }
    }
  ) {
    returning {
      id
    }
  }
}

and here is my atempt at updating mutation but update doesent have data property which i used in insert mutation

mutation recipe_edit(
  $title: String!
  $id: Int!
  $image: String!
  $description: String!
  $Date: date!
  $ingredient_relation: [ingredient_insert_input!]!
) {
  update_recipes(
    _set: {
      title: $title
      image: $image
      description: $description
      Date: $Date
    }
    where: { id: { _eq: $id } }
  ) {
    returning {
      id
    }
  }
  update_ingredient(
    _set: { data: $ingredient_relation }
    where: { recipe_id: { _eq: $id } }
  ) {
    returning {
      id
    }
  }
}

I also made fully working updating withouth variables it works only in hasura graphiql interface

mutation UpdateRecipe {
  update_recipes(_set: {title: "lets change title", image: "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5e/Vytautas_the_Great_Bridge_from_hill%2C_Kaunas%2C_Lithuania_-_Diliff.jpg/1280px-Vytautas_the_Great_Bridge_from_hill%2C_Kaunas%2C_Lithuania_-_Diliff.jpgs", description: "new description", Date: "1991-06-09"}, where: {id: {_eq: 10}}) {
    affected_rows
  }
  update_ingredient(_set: {name: "lets change the name"}, where: {recipe_id: {_eq: 10}}) {
    affected_rows
  }
}
Evaldas
  • 169
  • 7

1 Answers1

0

Unfortunately, you cannot update multiple records by ID in 1 mutation section.

There are 2 approaches I typically use for this issue.

1: use an insert mutation with an on_conflict constraint for the table ID and supply all columns you wish to update if they conflict to the update_columns parameter. You just declare a single variable of the [table]_insert_input type and pass in the updated record as a JS object (instead of passing in each value separately). You can nest child records here as well. You will need to declare conflict constraints and columns to update for the children as well. Messing around with the graphiql interface should help you figure out how to do this. This has the benefit of using the same query for both insert and update operations. It has the same downside as well... (permissions)

2: using code (presumably) you can generate as many update graphql sections as you'd like. Like so:

const MUTATION = `mutation UpdateRecipe {
  update_recipes(_set: {title: "lets change title", image: "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5e/Vytautas_the_Great_Bridge_from_hill%2C_Kaunas%2C_Lithuania_-_Diliff.jpg/1280px-Vytautas_the_Great_Bridge_from_hill%2C_Kaunas%2C_Lithuania_-_Diliff.jpgs", description: "new description", Date: "1991-06-09"}, where: {id: {_eq: 10}}) {
    affected_rows
  }
${
ingredients.map((ingrd, i) => `
update_ingredient_${i}: update_ingredient(_set: {name: ${ingrd.name}}, where: {id: {_eq: ${ingrd.id}}}) {
  returning { ... }
}
`).join("\n")
}
  
}`


Notice I prefixed each section because 1 query cannot have multiple sections of the same name.

While option 2 certainly feels "icky"er it has the single benefit of using the correct permission for the operation... Hope this helps

Abraham Labkovsky
  • 1,771
  • 6
  • 12