Prisma1: Relation has no Node for model

Created on 13 Jan 2018  ยท  25Comments  ยท  Source: prisma/prisma1

Current behavior
I'm able to create a relation between two Nodes via connect, but when attempting to disconnect, I'm unable to query either Node with a unique field.

Example:
_User B_ follows _User A_ via connect. Row added to the UserFollows relation.

  async follow(parent, args, ctx, info) {
    const auth0Id = await parseUserAuth0Id(ctx)
    return await ctx.db.mutation.updateUser({
      where: { username: args.username },
      data: {
        followers: {
          connect: [{ auth0Id }]
        }
      }
    })
  },

_User B_ unfollows _User A_ via disconnect. Error is thrown: The relation UserFollows has no Node for the model User with valueloganfor username connected to a Node for the model User with valuecjcdjow1t00310181tctl316ffor id, Location: [object Object], Path: updateUser

  async unfollow(parent, args, ctx, info) {
    const auth0Id = await parseUserAuth0Id(ctx)
    return await ctx.db.mutation.updateUser({
      where: { username: args.username },
      data: {
        followers: {
          disconnect: [{ auth0Id }]
        }
      }
    })
  }
}
bu2-confirmed

Most helpful comment

Awesome, upgraded the beta version locally and everything works as expected. Thanks to all involved for making that possible. ๐ŸŽ‰

@marktani This issue can be closed from my side :)

All 25 comments

What's your graphcool-binding version?

@marktani 1.3.5

Can you share your data model?

type User {
  id: ID! @unique
  auth0Id: String! @unique
  email: String! @unique
  email_verified: String
  username: String @unique
  name: String
  picture: String
  gender: String
  description: String
  video: String
  classes: [Class!]! @relation(name: "UserClasses") @default(value: []) @migrationValue(value: [])
  taughtClasses: [Class!]! @relation(name: "UserTaughtClasses") @default(value: []) @migrationValue(value: [])
  followers: [User!]! @relation(name: "UserFollows") @default(value: []) @migrationValue(value: [])
  following: [User!]! @relation(name: "UserFollowing") @default(value: []) @migrationValue(value: [])
}

still not sure if I even need following...

Thanks!

As a side comment, neither @default nor @migrationValue are supported on relation fields. Please remove them and deploy again ๐Ÿ™‚

after removing @default and @migrationValue and running gc deploy, it claims i'm still up to date, even if I use gc deploy -f

EDIT same results after redeploying

Raw Mutations:

follow

mutation ($_data: UserUpdateInput!, $_where: UserWhereUniqueInput!) {
  updateUser(data: $_data, where: $_where) {
    id
    auth0Id
    email
    email_verified
    username
    name
    picture
    gender
    description
    video
  }
}
operationName: null
variables:
{
  "_data": {
    "followers": {
      "connect": [
        {
          "auth0Id": "facebook|10155255936088549"
        }
      ]
    }
  },
  "_where": {
    "username": "test"
  }
}

unfollow

mutation ($_data: UserUpdateInput!, $_where: UserWhereUniqueInput!) {
  updateUser(data: $_data, where: $_where) {
    id
    auth0Id
    email
    email_verified
    username
    name
    picture
    gender
    description
    video
  }
}
operationName: null
variables:
{
  "_data": {
    "followers": {
      "disconnect": [
        {
          "auth0Id": "facebook|10155255936088549"
        }
      ]
    }
  },
  "_where": {
    "username": "test"
  }
}

error

"message": "The relation UserFollows has no Node for the model User with value `test` for username connected to a Node for the model User with value `facebook|10155255936088549` for auth0Id",
      "requestId": "api:api:cjcdokt1u0db30181iw7khyf0"

Thanks for reporting this @hoodsy . I could reproduce and fix this. This should be resolved with the next release. Same goes for the other issue you reported. I will close both issues once the fixes are released.

I can also reproduce this. Also, putting in the same id twice (both in the where and in the update objects) seems to work, although no change is made at the end.

This should be fixed now and the changes are rolled out.

@do4gr I'm still encountering this issue after upgrading:
Error: The relation UserFollowing has no Node for the model User with value 'facebook|10155255936088549' for auth0Id connected to a Node for the model User with value 'test' for username

There is a row in _UserFollowing that matches up for these values.

Happy to send any info that might be helpful.

I am hitting this as well.

Let me know what information you might need

@do4gr We're also facing this situation right now. Therefore, IMHO this issue should be opened again.

We have a similar data model like @hoodsy and also struggling with Prisma stating that the models are not connected which in fact is not true (database looks good). Unfortunately, this is a huge blocker for our team right now :(

Our user type looks like:

type User {
  id: ID! @unique
  role: Role! @default(value: "Member")
  banned: Boolean! @default(value: "false")
  username: String! @unique
  password: String!
  salt: String!
  followers: [User!]! @relation(name: "UserFollowers")
  follows: [User!]! @relation(name: "UserFollows")
}

@akoenig I had made an error or two in my logic that prolonged this issue for me. Here are my follow and unfollow mutations that work as intended:

  async follow(parent, { username }, ctx, info) {
    const auth0Id = await parseUserAuth0Id(ctx)
    await ctx.db.mutation.updateUser({
      where: { auth0Id },
      data: {
        following: {
          connect: [{ username }]
        }
      }
    })
    return await ctx.db.mutation.updateUser({
      where: { username },
      data: {
        followers: {
          connect: [{ auth0Id }]
        }
      }
    }, info)
  },

  async unfollow(parent, { username }, ctx, info) {
    const auth0Id = await parseUserAuth0Id(ctx)
    await ctx.db.mutation.updateUser({
      where: { auth0Id },
      data: {
        following: {
          disconnect: [{ username }]
        }
      }
    })
    return await ctx.db.mutation.updateUser({
      where: { username },
      data: {
        followers: {
          disconnect: [{ auth0Id }]
        }
      }
    }, info)
  },

Is there a more elegant solution? Probably (hopefully)... if someone has a better approach, I'd love to use it.

@hoodsy Glad to hear that it works for you ๐ŸŽ‰ Our mutations look similar, but still no luck ๐Ÿ˜ข

follow:

  const user = await context.db.mutation.updateUser({
      data: {
        follows: {
          connect: [{ id: userToFollow.id }]
        }
      },
      where: {
        id: context.user.id
      }
    },
    info
  );

  await context.db.mutation.updateUser({
    data: {
      followers: {
        connect: [{ id: context.user.id }]
      }
    },
    where: {
      id: userToFollow.id
    }
  });

unfollow:

 await context.db.mutation.updateUser(
    {
      data: {
        follows: {
          disconnect: [{ id: userToUnfollow.id }]
        }
      },
      where: {
        id: context.user.id
      }
    },
    info
  );

  await context.db.mutation.updateUser({
    data: {
      followers: {
        disconnect: [{ id: context.user.id }]
      }
    },
    where: {
      id: userToUnfollow.id
    }
  });

operating on this data model:

type User {
  id: ID! @unique
  role: Role! @default(value: "Member")
  banned: Boolean! @default(value: "false")
  username: String! @unique
  password: String!
  salt: String!
  followers: [User!]! @relation(name: "UserFollowers")
  follows: [User!]! @relation(name: "UserFollows")
}

Regarding a more elegant solution: Yeah, this is also my ๐ŸŽฏ Ideally, it would be possible to have those two transactions in one (with the help of a nested mutation). I created a forum post over here: Create bidirectional connection in one transaction.

Ah, forgot to mention: The problem only occurs when executing the unfollow mutation. So the question is: What is messing things up here? Connecting the nodes (executing follow) or trying to disconnect them (executing unfollow)?

Sorry for not replying earlier, I'll look into this now.

@do4gr That is awesome. Thanks for reconsidering this issue ๐Ÿ˜ƒ โ€“ I'm happy to help in providing more information if necessary.

@do4gr Thanks for your effort on this. I just tested the unstable channel with the prismagraphql/prisma:1.2-beta Docker image and have to say that the problem persists. I tried this mutation against the Prisma service API directly:

mutation {
  updateUser(data: {
    follows: {
      disconnect: [{
        id:"<id>",
      }],
    }
  }, where:{id:"<id>"})  {
    id
    username
  }
}

The response is still:

{
  "data": {
    "updateUser": null
  },
  "errors": [
    {
      "locations": [
        {
          "line": 6,
          "column": 3
        }
      ],
      "path": [
        "updateUser"
      ],
      "code": 3041,
      "message": "The relation UserFollows has no Node for the model User with value `<id>` for id connected to a Node for the model User with value `<id>` for id",
      "requestId": "api:api:cjdmyh82l00200188ggbuo63i"
    }
  ]
}

Sorry that I haven't better news ๐Ÿ˜ข

@do4gr Okay, just saw that prisma@beta is currently an old version and hasn't published yet. I changed the image in my prisma/cli/packages/prisma-cli-core/src/commands/local/docker/docker-compose.yml manually to 1.3-beta and performed a prisma local upgrade.

This version is superb and your fix works for me! ๐ŸŽ‰ Thanks! ๐Ÿ˜„

Any idea why the beta package hasn't shipped by the CI/CD yet?

Thanks @akoenig, created an issue for the beta release: https://github.com/graphcool/prisma/issues/1900

Awesome, upgraded the beta version locally and everything works as expected. Thanks to all involved for making that possible. ๐ŸŽ‰

@marktani This issue can be closed from my side :)

Thanks @hoodsy, @M-Zuber, @kitze and @akoenig for your help ๐Ÿ™

I was getting this error. I had a same data model and mutation. I tried all solution mentioned above. I didn't work well for me. Then, I removed followers connect and disconnect mutation. This solved my problem.

If you have same problem, it can be useful.

@akoenig I had made an error or two in my logic that prolonged this issue for me. Here are my follow and unfollow mutations that work as intended:

  async follow(parent, { username }, ctx, info) {
    const auth0Id = await parseUserAuth0Id(ctx)
    await ctx.db.mutation.updateUser({
      where: { auth0Id },
      data: {
        following: {
          connect: [{ username }]
        }
      }
    })
    return await ctx.db.mutation.updateUser({
      where: { username },
      data: {
        followers: {
          connect: [{ auth0Id }]
        }
      }
    }, info)
  },

  async unfollow(parent, { username }, ctx, info) {
    const auth0Id = await parseUserAuth0Id(ctx)
    await ctx.db.mutation.updateUser({
      where: { auth0Id },
      data: {
        following: {
          disconnect: [{ username }]
        }
      }
    })
    return await ctx.db.mutation.updateUser({
      where: { username },
      data: {
        followers: {
          disconnect: [{ auth0Id }]
        }
      }
    }, info)
  },

Is there a more elegant solution? Probably (hopefully)... if someone has a better approach, I'd love to use it.

Would love to know if there is a better way of doing this with one Mutation instead of having to do two separate updates to both Users?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

marktani picture marktani  ยท  3Comments

sorenbs picture sorenbs  ยท  3Comments

schickling picture schickling  ยท  3Comments

hoodsy picture hoodsy  ยท  3Comments

akoenig picture akoenig  ยท  3Comments