Sequelize отношения многие ко многим не показывает отношения при использовании GET REQUEST - PullRequest
1 голос
/ 31 марта 2020

Я новичок в реляционной базе данных. Я использую node js и express для бэкэнда, REST API и база данных Postgresql. Я использую Sequelize для подключения и моделей. Я создал две модели: одна студентка, а другая - курс. Моя цель - один студент может иметь несколько курсов, а также хочет предотвратить дублирование имени студента, телефона, электронной почты. Я успешно подключился к базе данных и смог опубликовать запрос. Конечно, я отправляю вот так: Изображение, конечно, отправляю запрос . Из тестирования приложения я использую Почтальон. Но когда я пытаюсь получить запрос от студентов или курсов. Я не вижу никакой связи между студентами и курсами . Вот визуализация студенты получают запрос и курсы получают запрос . Это живой код .

Это модель моего студента

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 };

Это моя НАСТРОЙКА API REST. Поступление запроса от студента и курса

//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);
  }
});

1 Ответ

0 голосов
/ 31 марта 2020

Так что, похоже, у вас здесь есть некоторые фундаментальные ошибки. Если отношение «многие ко многим», модель курса не должна иметь никакого внешнего ключа (studentId), потому что курс может иметь много студентов . Какой студент, если бы в этом курсе были студенты 1,2 и 3? Не имеет смысла (если вы не работаете с NO SQL, тогда у вас может быть массив идентификаторов в качестве ссылок).

Именно здесь "таблица соединений" входит в картину, единственной целью которой является хранить отношения между курсом и студентом. Удалите столбец studentId из курса.

Кроме того, я бы поставил autoIncrement: true на предварительные ключи, потому что без него вам придется вручную создавать идентификатор, что очень неправильно. Что касается электронного письма, оно должно быть уникальным: true.

Мне также пришлось изменить все типы с sequelize [type] на DataTypes [type]. Вы не получаете никакой ошибки?

Я протестировал ваш код (без неправильного столбца, конечно), с небольшими изменениями, и маршруты GET, кажется, работают (я не тестировал POST, просто вставил записи вручную в БД). Вы уверены, что у вас есть записи?

Попробуйте это без лишнего внешнего ключа в модели курса. Убедитесь, что у вас есть записи в БД (потому что, возможно, проблема в POST, а не в GET). Если это не работает, предоставьте больше деталей и код.

Добавлена ​​картинка, показывающая, что GET работает для меня: enter image description here

Редактировать: Документы по сиквелизу, на мой взгляд, очень плохие, и, честно говоря, я больше не использую этот 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 (при условии, что этот курс, конечно, существует).

Обратите внимание, что это действительно очень плохо: он выполняет ненужный запрос для извлечения курса по его идентификатору, просто чтобы иметь возможность использовать функцию student.addCourse. Я предполагаю, что есть более эффективные способы сделать это с помощью Sequelize, которые вам необходимо изучить в документах и ​​руководствах. Лично я никогда бы не сделал это таким образом, я бы просто выполнил необработанный запрос к соединительной таблице, добавив отношение, полагаясь на userId и courseId, поступающие через AJAX, на отдельный маршрут, который я, возможно, назову "addStudentCourse" ». Если вы хотите знать, как это сделать, дайте мне знать.

Опять же: я нахожу документацию по сиквелизму настолько плохо написанной, что лучше не использовать этот ORM. Кроме того, обучение SQL очень полезно для карьеры. Имейте это в виду: D

...