Prisma1: Replace connected nodes for to-many relation

Created on 7 Mar 2018  路  22Comments  路  Source: prisma/prisma1

Feature Request

What feature are you missing?

A nested "replace" or "set" mutation, that would _set_ the connected nodes for a given node and relation.

Currently, only connect/disconnect are available. This means that it's possible to manually accomplish it right now, but requires an additional query of connected nodes first.

How could this feature look like in detail? Tradeoffs?

One trade off I can think of is whether or not set could be combined with other nested mutations or or not.

Consider this data model:

type User {
  id: ID! @unique
  name: String!
  posts: [Post!]!
}

type Post {
  id: ID! @unique
  title: String!
  slug: String! @unique
}

Suggestion A - set can only be used on its own

mutation {
  updateUser(
    where: {
      id: "my-id"
    }
    data: {
      posts: {
        set: [{
          id: "my-post-id"
        }, {
          slug: "my-post-slug"
        }]
      }
    }
  )
}

Suggestion B - set + other nested mutations can be used together

Here I used connect as an example. Could also be used with create and upsert, update, disconnect. This requires more thought, and an execution order would need to be defined. Example: Is disconnect executed before or after set?

mutation {
  updateUser(
    where: {
      id: "my-id"
    }
    data: {
      posts: {
        set: [{
          id: "my-post-id"
        }, {
          slug: "my-post-slug"
        }]
        connect: [{
          id: "another-post-id"
        }, {
          slug: "another-post-slug"
        }]
      }
    }
  )
}
kinfeature areapi rf2-accepted

Most helpful comment

The feature is now in Alpha and will be promoted to the Beta later today.

All 22 comments

would love to see this makes a lot of sense

Looking forward to this as well -- this convenient feature was previously available in Graphcool Framework.. one could easily replace all connected nodes by supplying a new list of node ids.

See: https://www.graph.cool/docs/reference/graphql-api/mutation-api-ol0yuoz6go#modifying-edges-for-one-to-one-relations ... "

...will replace the existing list of nodes

@marktani - I think suggestion A is good first step forward, B will definitely require more thought and requires deeper transactional guarantees.

This would be a great, likely-well-used feature because it would solve a common problem that is ripe for abstraction.

I am looking forward for this too :)

Same here 馃憤. Without it, it leads to pretty complex resolvers, where everything needs to be computed by hand. https://github.com/Weakky/prisma-ecommerce/blob/master/prisma/src/resolvers/Mutation/option.ts#L8-L24

+1 almost all update resolver need this feature. suggestion A is better.

+1 for suggestion A ;)

Do you plan to implement this feature? do you have an estimate date of delivery?
Thanks for your answer and I'm sorry for my english

+1 for suggestion A 馃憤

+1 for suggestion A.

Sending nested form data in order to update relations should not require to query the previously connected nodes.

We will implement Suggestion A described above. If set is used together with other submutations such as connect or disconnect, Prisma will abort the operation and return an error.

@Weakky, @Huvik and everybody else who is interested in this feature - if you have any specific requirements or corner cases that might not be covered by this proposal, now is the time to document them here, so we can create the best possible implementation of this feature 馃檹

If it's going be implemented like suggestion A, I don't see any edge case, because its just going to replace relations. I know that B is hard to implement, so from my point of view A is good for now.

We have started implementing proposal A.

The feature is now in Alpha and will be promoted to the Beta later today.

Would have loved to see upserting work with this. But you went too fast on this one :)

A common use case is a tags field as a relation to [Tag]. In a form you would be able to select an existing tag or create a new one. And submitting would replace all tags and create new ones.

I don't fully understand what you mean @jide, can you give a complete example please?

From a end user perspective, it would be a tags input allowing to choose from a list of existing tags, and also allowing to create a new one, like this :

capture d ecran 2019-02-01 a 11 58 20

I guess it would need a mutation roughly like this to be possible :

mutation {
  updatePost(
    where: {
      id: "my-id"
    }
    data: {
      tags: {
        set: [{
          connect: {
            title: "Sport"
          },
          create: {
            title: "Sport",
            other: "Example"
          }, {
          connect: {
            title: "New tag"
          },
          create: {
            title: "New tag",
            other: "Example 2"
          }
        }]
      }
    }
  )
}

Hey, what about merging in Beta ? @do4gr

What do you mean @cormarti? This should already be available in Master.

I confirm that new feature is working, in my case was necessary in a multi input tag component.
The mutation is like follow example:

...
subjects: this.tags.length ? {
    set: this.tags.map(i => {
        return {
            id: i.id
        }
    })
}

馃憦 馃憦
Great work Prisma guys! :D

Good to hear that you're making use of it @raulghm !

I'm closing the issue since the feature is now available.

That'd be nice to implement set on upserts too!

For reference, I get this error when I try to use it on an upsert, and thus have to revert back to insert / update scheme:

Field 'set' is not defined in the input type [CHILD]CreateManyWithout[PARENT]Input

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AlessandroAnnini picture AlessandroAnnini  路  3Comments

schickling picture schickling  路  3Comments

schickling picture schickling  路  3Comments

Fi1osof picture Fi1osof  路  3Comments

tbrannam picture tbrannam  路  3Comments