Sequelize - Associating 4 tables

ぐ巨炮叔叔 提交于 2019-12-25 09:17:13

问题


Am trying to associate 4 tables. Tasks, TaskQuestions, Questions and Options.

My models are as follows

Tasks model:

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 model:

var Sequelize = require('sequelize');

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

Questions model:

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

Options model:

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

When I try to retrieve the data

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

All I get is the association between Task and Questions. When I retrieve Questions individually I get Options under it. But can't seem to retrieve all at once.

Is it even possible. And let me know if am following the right approach designing the database in this format.

I need one task to contain multiple questions and same questions can appear in multiple tasks. Each question should contain multiple options.


回答1:


Yes, it's possible, and is covered in the documentation at http://docs.sequelizejs.com/en/latest/docs/models-usage/#nested-eager-loading

Basically, rather than putting a model like models.Question in your include array, you put an object, with a key for model and a key for the nested include's

For your example above, something like this should do the trick:

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


来源:https://stackoverflow.com/questions/41671377/sequelize-associating-4-tables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!