寻找在 Amplify / React 中使用 GraphQL 创建和更新项目的正确方法

问题描述 投票:0回答:1

我是 Amplify、React 和 GraphQL 的新手。我正在寻找正确的方法来进行表之间具有@hasMany 关系的突变(对于上下文,我正在使用多表解决方案,因为这似乎最适合 Amplify)。

我正在尝试构建一个应用程序,它有一个用户,每个用户有几个孩子,每个孩子都有故事......我完全不知道如何在多个表之间建立这个 @hasMany 连接和更新。

这是我的 schema.graphql:

type User @model @auth(rules: [{allow: owner}]) {
  id: ID!
  email: String! @index(name: "byEmail", queryField: "userByEmail", sortKeyFields: ["id"])
  children: [Child] @hasMany
  settings: String
  lastInteraction: String
}

type Child @model @auth(rules: [{allow: owner}]) {
  id: ID!
  name: String!
  age: String!
  commonNoun: String!
  user: User @belongsTo
  stories: [Story] @hasMany
}

type Story @model @auth(rules: [{allow: owner}]) {
  id: ID!
  child: Child @belongsTo
  status: String
  storyType: String
  storyData: String!
}
 

我已经能够成功创建一个用户和一个孩子,但现在我想将两者联系起来。到目前为止,这是我创建用户的代码:

export async function createNewUserinDB(userEmail) {
      
  const data = {
    email: userEmail
  };

  const userCreationResponse = await API.graphql({
    query: createUser,
    variables: { input: data },
    authMode: "AMAZON_COGNITO_USER_POOLS"
  }).then(response => {
    console.log(response);
    return response;
  }).catch(e => {
    console.log("catch");
      console.log(e);
      return null;
  });

  return(userCreationResponse);

}

为了创造一个孩子:

async function createChildinDB(childAge, childName, childCommonNoun, userID) {
      
    const data = {
      age: childAge,
      name: childName,
      commonNoun: childCommonNoun,
    };

    const childCreationResponse = await API.graphql({
      query: createChild,
      variables: { input: data },
      authMode: "AMAZON_COGNITO_USER_POOLS"
    }).then(response => {
      console.log(response);
      return response;
    }).catch(e => {
        console.log(e);
        return null;
    });

    return(childCreationResponse);

  }

我已经尝试创建一个单独的函数来将已经创建的 Child 传递给 UserUpdate,但我似乎做对了。执行以下代码时出现此错误:“变量输入包含未为输入对象类型‘UpdateUserInput’定义的字段名称‘children’”

export async function addChildtoUserInDB(userID, userEmail, childData) {
      
  const data = {
    id: userID,
    email: "Sparky", // this was for testing; works fine if this line exists but no line below
    children: [childData]
  };

  console.log(childData);

  const updateUserResponse = await API.graphql({
    query: updateUser,
    variables: { input: data },
    authMode: "AMAZON_COGNITO_USER_POOLS"
  }).then(response => {
    console.log(response);
    return response;
  }).catch(e => {
    console.log("catch");
      console.log(e);
      return null;
  });

  return(updateUserResponse);

}

如果我注释掉关于“孩子”的那一行,代码就可以正常工作。我尝试过各种不同的东西;例如去掉括号和不同的格式,改成 Child,不同版本的this String solution,我也发现了这个input type thing,但感觉它与多个@hasMany table references 不兼容。

我还找到了 this solution 在引用父项的同时创建子项/叶项,但不确定如何调整它,因为最后一个代码示例“userToDoItemsOwner”中的语法似乎无处不在。

在这里欢迎任何想法;我感觉很困! :)

reactjs graphql aws-amplify has-many graphql-mutation
1个回答
0
投票

我想通了!我最终将我的架构稍微修改为以下内容,根据卢克的建议删除了@belongsTo:

type User @model @auth(rules: [{allow: owner}]) {
  id: ID!
  email: String! @index(name: "byEmail", queryField: "userByEmail", sortKeyFields: ["id"])
  children: [Child] @hasMany
  settings: String
  lastInteraction: String
}

type Child @model @auth(rules: [{allow: owner}]) {
  id: ID!
  name: String!
  age: String!
  commonNoun: String!
  stories: [Story] @hasMany
}

type Story @model @auth(rules: [{allow: owner}]) {
  id: ID!
  status: String
  storyType: String
  storyData: String!
}

正确的模式是在使用“userChildrenId”引用用户 ID 的同时创建子项目。这是与拥有用户项目关联的子对象的创建代码:

  async function createChildinDB(childAge, childName, childCommonNoun, userID) {
      
    const data = {
      age: childAge,
      name: childName,
      commonNoun: childCommonNoun,
      userChildrenId: userID
    };

    const childCreationResponse = await API.graphql({
      query: createChild,
      variables: { input: data },
      authMode: "AMAZON_COGNITO_USER_POOLS"
    }).then(response => {
      return response;
    }).catch(e => {
        console.log(e);
        return null;
    });

    return(childCreationResponse);

  }

有了这个模式,我仍然能够成功查询与特定用户关联的所有孩子:

export async function getChildrenforUser(userID) {

  // filter on only children of user
  const variablesForChildrenofUserQuery = {
    filter: {
      userChildrenId: {
        eq: userID
      }
    }

  }

  const getUserChildren = await API.graphql({
    query: listChildren,
    variables: variablesForChildrenofUserQuery,
    authMode: "AMAZON_COGNITO_USER_POOLS"
  }).then(response => {
    console.log(response);
    return response;
  }).catch(e => {
      console.log(e);
      return null;
  });

  return(getUserChildren);
}

希望这对将来的其他人有帮助:)

© www.soinside.com 2019 - 2024. All rights reserved.