【问题标题】:Sequelize many to many relationship does not show relationship when using GET REQUEST使用 GET REQUEST 时,续集多对多关系不显示关系
【发布时间】:2020-03-31 03:14:33
【问题描述】:

我是关系数据库的新手。我正在使用 node js 并表示后端,REST API 和数据库是 Postgresql。我正在使用 Sequelize 进行连接和模型。我创建了两个模型,一个是学生,另一个是课程。我的目标是一个学生可以有多个课程,并且还想防止重复的学生姓名、电话、电子邮件。我成功连接到数据库并能够发布请求。当然,我是这样发帖的,Image of course post request。通过测试我正在使用 Postman 的应用程序。但是当我试图从学生或课程中获得请求时。 我认为学生与课程之间没有任何关系。这是可视化students get requestcourses get request这是live code

这是我的学生模型

const Student = con.define("student", {
      id: {
        type: sequelize.INTEGER,
        primaryKey: true
      },
      name: {
        type: sequelize.STRING,
        allowNull: false
      },
      birthday: {
        type: sequelize.DATEONLY,
        allowNull: false
      },
      address: {
        type: sequelize.STRING,
        allowNull: false
      },
      zipcode: {
        type: sequelize.INTEGER,
        allowNull: false
      },
      city: {
        type: sequelize.STRING,
        allowNull: false
      },
      phone: {
        type: sequelize.BIGINT,
        allowNull: false
      },

      email: {
        type: sequelize.STRING,
        allowNull: false,
        validate: {
          isEmail: true
        }
      }
    });

这是课程模型

const Course = con.define("course", {
  name: { type: sequelize.STRING },
  startdate: { type: sequelize.DATEONLY },
  enddate: { type: sequelize.DATEONLY },
  studentId: { type: sequelize.INTEGER, foreignKey: true }
});

这是我的多对多关系设置

const StudentCourse = con.define("studentCourses", {
  id: {
    type: sequelize.INTEGER,
    primaryKey: true
  },
  courseId: { type: sequelize.INTEGER, foreignKey: true },
  studentId: { type: sequelize.INTEGER, foreignKey: true }
});

Student.belongsToMany(Course, { through: StudentCourse, as: "courses" });
Course.belongsToMany(Student, { through: StudentCourse, as: "students" });

//con.sync({ force: true });

module.exports = { Student, Course, StudentCourse };

这是我的 REST API 设置。学生和课程发帖请求

//Student post request
    app.post("/students", async (req, res, next) => {
      try {
        const logs = new Student(req.body);
        const entry = await logs.save();
        res.json(entry);
      } catch (error) {
        if (error.name === "ValidationError") {
          res.status(422);
        }
        next(error);
      }
    });


//Course post request 

    app.post("/courses", async (req, res, next) => {
      try {
        const logs = new Course(req.body);
        const entry = await logs.save();
        res.json(entry);
      } catch (error) {
        if (error.name === "ValidationError") {
          res.status(422);
        }
        next(error);
      }
    });

*这是我没有看到结果的学生和课程的获取请求设置

app.get("/student", async (req, res, next) => {
  try {
    await Student.findAll({
      include: {
        model: Course,
        through: StudentCourse,
        as: "courses"
      }
    }).then(docs => {
      res.json(docs);
    });
  } catch (error) {
    console.log(error);
  }
});

app.get("/course", async (req, res, next) => {
  try {
    await Course.findAll({
      include: {
        model: Student,
        through: StudentCourse,
        as: "students"
      }
    }).then(docs => {
      res.json(docs);
    });
  } catch (error) {
    console.log(error);
  }
});

【问题讨论】:

    标签: node.js express sequelize.js many-to-many


    【解决方案1】:

    所以看来你这里有一些根本性的错误。如果关系是多对多,Course 模型不应该有任何外键(studentId),因为一个课程可以有许多学生。如果这门课程有学生 1,2 和 3,那会是什么学生 ID?没有意义(除非您使用 NOSQL,否则您可以使用 id 数组作为引用)。

    这就是“连接表”出现的地方,其唯一目的是存储课程和学生之间的关系。从 Course 中删除 studentId 列。

    另外,我会将 autoIncrement:true 放在主键上,因为如果没有它,您将需要手动创建 ID,这是非常错误的。关于电子邮件,它需要具有唯一性:true。

    我还必须将所有类型从 sequelize[type] 更改为 DataTypes[type]。你没有收到任何错误?

    我测试了您的代码(当然没有错误的列),稍作修改,GET 路由似乎有效(我没有测试 POST,只是手动将记录插入数据库)。你确定你有记录吗?

    在课程模型中尝试不使用不必要的外键。确保您在数据库中有记录(因为问题可能出在 POST 中,而不是 GET 中)。如果它不起作用,请提供更多详细信息和代码。

    添加了一张图片以显示 GET 对我有用:

    编辑:在我看来,sequelize 的文档很差,老实说,我不再使用这个 ORM。但这就是我设法发布一个有关系的学生的方式:

    app.post("/students", async (req, res, next) => {
        try {
    
          const student = await Student.create(req.body)
          const course = await Course.findOne({where:{id:1}})//Get the course you want to "add" to the user, by id.
          //Notice that here the id hard-coded. You will need to supply it from where-ever..
          await student.addCourse(course)
          res.json(student);
        } catch (error) {
          if (error.name === "ValidationError") {
            res.status(422);
          }
          next(error);
        }
      });
    

    这条路线创建一个学生,并将其与 ID 1 的课程相关联(假设该课程当然存在)。

    请注意,这实际上非常糟糕:它执行了一个不必要的查询来通过其 ID 获取课程,只是为了能够使用 student.addCourse 函数。我认为使用 Sequelize 有更好的方法,您需要在文档和教程中进行探索。我个人永远不会这样做,我只会对联结表执行原始查询,将依赖于通过 AJAX 传入的 userId 和 courseId 的关系添加到单独的路由中,我可能会称之为“addStudentCourse”。如果您想知道如何执行此操作,请告诉我。

    再次:我发现 sequelize 文档写得太差了,最好不要使用这个 ORM。此外,学习 SQL 对一个人的职业生涯非常有益。记住这一点:D

    【讨论】:

    • 嗨,非常感谢你这么好的建议。我添加了 autoIncrement:true 和 unique:true 。我在这个关系数据库中真的很新。我有几个问题要问你: 1. 如果我想在课程中添加一个学生,那么我如何添加它。因为没有学生证,我无法添加它们。 2. 哪部分代码需要修改?这是我的全部代码:codeshare.io/2KpbzX PS:是的,我可以存储数据。
    • 我对你来说听起来很愚蠢。如何在前端发帖。例如:我想为学生添加课程。这是我的应用程序的目标:codeshare.io/2KpbzX
    • 好吧,AJAX 有点超出你的问题范围......当然我可以为你写一个示例代码,但我认为你需要自己学习基础知识 - 更多对你有益。 Udemy 上有非常适合初学者的课程,如果您愿意,我可以推荐一些。
    • 当然可以。请把链接发给我。
    • 所以我的问题,没有简单的解决方案:D
    猜你喜欢
    • 2015-05-16
    • 1970-01-01
    • 1970-01-01
    • 2020-07-10
    • 2014-03-29
    • 1970-01-01
    • 2020-07-10
    • 1970-01-01
    相关资源
    最近更新 更多