Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to `include` two separate references of same model using Sequelize ORM?

Tags:

sequelize.js

I'm building a website using the MEAN stack but replacing MongoDB with PostGRES and, as a result, using Sequelize ORM.

I have two models -- User and AudioConfig. A User can have many AudioConfig and an AudioConfig belongs to a User by the createdBy and updatedBy.

Here's how my association looks like using Sequelize

models.User.hasMany(models.AudioConfig, {
  foreignKey: {
    name: 'createdBy',
    allowNull: false
  }
});
models.User.hasMany(models.AudioConfig, {
  foreignKey: {
    name: 'updatedBy'
  }
});
models.AudioConfig.belongsTo(models.User, {
  foreignKey: {
    name: 'createdBy',
    as: 'createdBy',
    allowNull: false
  }
});
models.AudioConfig.belongsTo(models.User, {
  foreignKey: {
    name: 'updatedBy',
    as: 'updatedBy'
  }
});

In my findAll query for AudioConfig, I have tried several variations from what I've found online but none appear to work as I expect:

var Db = require('../../models');
var entityModel = Db.AudioConfig;

exports.index = function (req, res) {
  entityModel.findAll({
      include: {all:true}
    })
    .then(function (entities) {
      return res.status(200).json(entities);
    })
    .catch(function (err) {
      return handleError(res, err);
    })
};

// And I've tried this...
exports.index = function (req, res) {
  entityModel.findAll({
      include: [
        {model: Db.User, as: 'createdBy'},
        {model: Db.User, as: 'updatedBy'}
      ]
    })
    .then(function (entities) {
      return res.status(200).json(entities);
    })
    .catch(function (err) {
      return handleError(res, err);
    })
};

// And this too...
exports.index = function (req, res) {
  entityModel.findAll({
      include: [
        {
          model: Db.User
        }
      ]
    })
    .then(function (entities) {
      return res.status(200).json(entities);
    })
    .catch(function (err) {
      return handleError(res, err);
    })
};

Now, in my database, I have a single record of AudioConfig that has two different User references -- one for createdBy and another for updatedBy. But when I do a query for AudioConfig, I only get the User record back for the updatedBy field.

[
  {
    "id": "e3011e31-b907-47ad-99f3-61016283a523",
    "sampleRate": 16000,
    "format": "WAV",
    "channel": 2,
    "bitRate": 16,
    "createdAt": "2016-05-01T16:30:11.847Z",
    "updatedAt": "2016-05-01T16:30:11.847Z",
    "createdBy": "1375263f-a3f0-4eef-800f-99b28fdce9d8",
    "updatedBy": "5bb8cac0-b916-4000-81fe-9b1f8f597847",
    "User": {
      "id": "5bb8cac0-b916-4000-81fe-9b1f8f597847",
      "email": "[email protected]",
      "firstName": "John",
      "lastName": "Doe",
      "resetPasswordToken": null,
      "resetPasswordTokenExpiresOn": null,
      "createdAt": "2016-05-01T16:30:11.816Z",
      "updatedAt": "2016-05-01T16:30:11.816Z",
      "roleId": "10ae3879-9f9f-4370-aa47-3677c492afd8"
    }
  }
]

How do I get it so that createdBy value of UUID is replaced with the User object associated with it? And same for the updatedBy field?

I'm somewhat expecting the same behavior as with MongoDB and Mongoose's populate

like image 698
FilmiHero Avatar asked May 01 '16 16:05

FilmiHero


People also ask

How do you include two models in Sequelize?

How do you include two models in Sequelize? Your solution, along with using include: {all:true} in my findAll query, did the trick. instead of using include: {all:true} in findAll you can use include: {model: models. User, as: 'createdByUser'} , etc.

How do you do a one to many relationship in Sequelize?

Creating the standard relationships​ To create a One-To-One relationship, the hasOne and belongsTo associations are used together; To create a One-To-Many relationship, the hasMany and belongsTo associations are used together; To create a Many-To-Many relationship, two belongsToMany calls are used together.

How do I insert multiple rows into Sequelize?

Adding multiple rows at once using Sequelize bulkCreate() method. When you need to insert multiple rows to your SQL database table, you can use the Sequelize bulkCreate() method. The bulkCreate() method allows you to insert multiple records to your database table with a single function call.


1 Answers

I finally realized what the problem is, you have the as property set on the foreign key object. This should hopefully solve it, unfortunately I can't test it myself at the moment.

models.User.hasMany(models.AudioConfig, {
  as: 'createdByUser',
  foreignKey: {
    name: 'createdBy',
    allowNull: false
  }
});
models.User.hasMany(models.AudioConfig, {
  as: 'updatedByUser',
  foreignKey: {
    name: 'updatedBy'
  }
});
models.AudioConfig.belongsTo(models.User, {
  as: 'createdByUser',
  foreignKey: {
    name: 'createdBy',
    allowNull: false
  }
});
models.AudioConfig.belongsTo(models.User, {
  as: 'updatedByUser'
  foreignKey: {
    name: 'updatedBy'
  }
});
like image 183
grimurd Avatar answered Oct 21 '22 04:10

grimurd