Sequelize - 关联4个表

时间:2017-01-16 07:27:26

标签: mysql node.js sequelize.js

我试图关联4个表。任务,任务问题,问题和选项。

enter image description here

我的模型如下

任务模型:

var Sequelize = require('sequelize');

module.exports = function(sequelize, DataTypes) {
  var Task = sequelize.define('Task', {
    task_id: {
      type: Sequelize.STRING,
      primaryKey: true
    },
    task_name: {
      type: Sequelize.STRING,
      allowNull: true
    },
    task_description: {
      type: Sequelize.STRING,
      allowNull: true
    }
  },{
    classMethods: {
      associate: function(models) {
        Task.belongsToMany(models.Question, {
          through: {
            model: models.TaskQuestion
          },
          foreignKey: 'task_id'
        })
      }
    }
  });
  return Task;
};

TaskQuestions模型:

var Sequelize = require('sequelize');

module.exports = function(sequelize, DataTypes) {
  var TaskQuestion = sequelize.define('TaskQuestion', {
    tq_id: {
      type: Sequelize.STRING,
      primaryKey: true
    }
  });
  return TaskQuestion;
};

问题模型:

var Sequelize = require('sequelize');

module.exports = function(sequelize, DataTypes) {
  var Question = sequelize.define('Question', {
    question_id: {
      type: Sequelize.STRING,
      primaryKey: true
    },
    question_description: {
      type: Sequelize.STRING,
      allowNull: true
    },
    question_type: {
      type: Sequelize.STRING,
      allowNull: true
    }
  },{
    classMethods: {
      associate: function(models) {
        Question.hasMany(models.Option, {
          foreignKey: {
            name: 'question_id',
            allowNull: false
          }
        }),
        Question.belongsToMany(models.Task, {
            through: {
                model: models.TaskQuestion
            },
            foreignKey: 'question_id'
        })
      }
    }
  });
  return Question;
};

选项模型:

var Sequelize = require('sequelize');

module.exports = function(sequelize, DataTypes) {
  var Option = sequelize.define('Option', {
    option_id: {
      type: Sequelize.STRING,
      primaryKey: true
    },
    question_id: {
      type: Sequelize.STRING,
      allowNull: true
    },
    option_description: {
      type: Sequelize.STRING,
      allowNull: true
    },
    option_type: {
      type: Sequelize.STRING,
      allowNull: true
    }
  },{
    classMethods: {

    }
  });
  return Option;
};

当我尝试检索数据时

router.get('/:task_id', function(req, res) {
  models.Task.findOne({
    where: {
      task_id: req.params.task_id
    },
    include: [ models.Question ]
  }).then(function(task) {
    res.json(task);
  });
});

我得到的是任务和问题之间的关联。当我单独检索问题时,我会得到选项。但似乎无法立即检索所有内容。

甚至可能。如果我采用这种格式设计数据库的正确方法,请告诉我。

我需要一个任务来包含多个问题,同一个问题可以出现在多个任务中。每个问题都应包含多个选项。

1 个答案:

答案 0 :(得分:1)

是的,这是可能的,并且在http://docs.sequelizejs.com/en/latest/docs/models-usage/#nested-eager-loading

的文档中有所介绍

基本上,不是在include数组中放置models.Question之类的模型,而是放置一个对象,其中包含model的键和嵌套include的键

对于上面的例子,这样的事情可以解决问题:

router.get('/:task_id', function(req, res) {
  models.Task.findOne({
    where: {
      task_id: req.params.task_id
    },
    include: [{
      model: models.Question,
      include: [models.Option]
    }]
  }).then(function(task) {
    res.json(task);
  });
});
相关问题